package com.yanqu.road.server.manager.cross.battle;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.huashigang.*;
import com.yanqu.road.entity.enums.activity.huashigang.eHuaShiGangEventBigType;
import com.yanqu.road.entity.enums.activity.huashigang.eHuaShiGangEventType;
import com.yanqu.road.entity.enums.activity.huashigang.eHuaShiGangMessageType;
import com.yanqu.road.entity.enums.activity.huashigang.eHuaShiGangSwitchType;
import com.yanqu.road.entity.enums.eActivityConfigType;
import com.yanqu.road.entity.enums.eRedHotNotifyType;
import com.yanqu.road.entity.enums.eSceneActionType;
import com.yanqu.road.entity.enums.eSceneType;
import com.yanqu.road.entity.log.cross.HuaShiGangHelperLog;
import com.yanqu.road.entity.player.ReturnData;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.rank.cross.CrossUserRank;
import com.yanqu.road.entity.scene.ScenePlayerInfo;
import com.yanqu.road.entity.scene.UserScene;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.logic.activity.HuaShiGangLogic;
import com.yanqu.road.logic.bussiness.activity.HuaShiGangActivityBusiness;
import com.yanqu.road.logic.bussiness.player.activity.auto.reward.UserHuaShiGangBusiness;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.cross.CrossActivityRankListModel;
import com.yanqu.road.logic.helper.ActivityHelper;
import com.yanqu.road.logic.pb.CrossRankPb;
import com.yanqu.road.logic.pb.HuaShiGangPb;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.logic.pb.ScenePb;
import com.yanqu.road.pb.activity.ActivityDisperseGoldProto;
import com.yanqu.road.pb.huashigang.HuaShiGangProto;
import com.yanqu.road.pb.scene.SceneProto;
import com.yanqu.road.pb.worldmessage.WorldMessageProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.cross.battle.enums.HuaShiGangBuildMode;
import com.yanqu.road.server.manager.cross.battle.enums.eHuaShiGangModeType;
import com.yanqu.road.server.manager.log.CrossAutoLogMgr;
import com.yanqu.road.server.manager.scene.CrossSceneMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.ZipUtils;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.awt.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @Author wpj
 * @Date 2020/10/3
 */
public class HuaShiGangActivity {

    private Logger logger = LogManager.getLogger(HuaShiGangActivity.class.getName());

    HuaShiGangNewConfig newConfig;

    ActivityInfo activityInfo;

    List<HuaShiGangMode> huaShiGangModeList;

    HuaShiGangData huaShiGangData;

    /**
     * 事件配置（ 事件ID，配置 ）
     */
    Map<Integer, HuaShiGangActivityEventConfig> huaShiGangActivityEventConfigMap;

    /**
     * 模块事件。K:阶段ID, K:事件大类型（eHuaShiGangEventBigType） V:事件列表结构。构造这个数据结构，方便查询。（用少了的内存空间，减少大量的遍历）
     */
    Map<Integer, Map<Integer, HuaShiGangStageBigTypeEvents>> huaShiGangStageBigTypeEventsMap;

    Map<String, List<HuaShiGangMonsterData>> huaShiGangMonsterDataMap;

    Map<String, List<HuaShiGangTreasure>> huaShiGangTreasureMap;

    Map<String, Map<Long, Set<Long>>> inTreasurePlayers = new ConcurrentHashMap<>();


    /**
     * 攻击伤害记录（ XY坐标，怪物ID，用户ID，记录 ）
     */
    Map<String, Map<Integer, Map<Long, HuaShiGangAttackRecord>>> attackRecordMap;

    /**
     * 精英怪排行奖励（ Y坐标，List奖励 ）
     */
    Map<Integer, List<HuaShiGangEliteReward>> eliteRewardMap;

    /**
     * 怪物伤害排行（ XY坐标，怪物ID ）
     */
    Map<String, Map<Integer, CrossActivityRankListModel>> monsterRankListModelMap;

    Map<Long, HuaShiGangUserData> userDataMap;

    Map<Long, Object> userLocker;

    CrossActivityRankListModel crossRankListModel;

    UserBaseInfo killBossUserBaseInfo;

    public UserBaseInfo getKillBossUserBaseInfo() {
        return killBossUserBaseInfo;
    }

    public Map<String, Map<Long, Set<Long>>> getInTreasurePlayers() {
        return inTreasurePlayers;
    }

    HuaShiGangUserData lastHuaShiGangData = new HuaShiGangUserData();

    private RandomHelper randomHelper = new RandomHelper();

    public HuaShiGangUserData getLastHuaShiGangData() {
        return lastHuaShiGangData;
    }

    public HuaShiGangData getHuaShiGangData() {
        return huaShiGangData;
    }

    public HuaShiGangAttackRecord addAttackRecord(int x, int y, int monsterId, long userId, long serverId, UserBaseInfo userBaseInfo, long damage) {

        // 普通怪物不生成排行榜 直接退出
        HuaShiGangMode mode = getModeByY(y);
        if (mode != null && mode.getModeType() == eHuaShiGangModeType.A) {
            return null;
        }

        String key = HuaShiGangMgr.getKey(x, y);
        if (!attackRecordMap.containsKey(key)) {
            attackRecordMap.put(key, new ConcurrentHashMap<>());
        }
        if (!attackRecordMap.get(key).containsKey(monsterId)) {
            attackRecordMap.get(key).put(monsterId, new ConcurrentHashMap<>());
        }
        HuaShiGangAttackRecord record = attackRecordMap.get(key).get(monsterId).get(userId);
        if (record == null) {
            record = new HuaShiGangAttackRecord();
            record.setActivityId(activityInfo.getActivityId());
            record.setPointKey(key);
            record.setMonsterId(monsterId);
            record.setServerId(serverId);
            record.setUserId(userId);
            record.setDamage(0);
            record.setUpdateTime(0);
            record.setUserBaseInfo(userBaseInfo);
            record.setInsertOption();
            attackRecordMap.get(key).get(monsterId).put(userId, record);
        }

        record.setUpdateTime(System.currentTimeMillis());
        record.setDamage(record.getDamage() + damage);
        record.setUserBaseInfo(userBaseInfo);

        CrossActivityRankListModel model = getMonsterRankListModel(x, y, monsterId);
        CrossUserRank rank = new CrossUserRank();
        rank.setUserBaseInfo(record.getUserBaseInfo());
        rank.setUserId(record.getUserId());
        rank.setLastUpdateTime(record.getUpdateTime());
        rank.setValue(BigInteger.valueOf(record.getDamage()));
        model.rankChange(rank);
        return record;
    }

    /**
     * 获取怪物伤害排行榜
     *
     * @param x
     * @param y
     * @param monsterId
     * @return
     */
    public CrossActivityRankListModel getMonsterRankListModel(int x, int y, int monsterId) {

        // 普通怪物不生成排行榜 直接返回空列表 不写入到内存
        HuaShiGangMode mode = getModeByY(y);
        if (mode != null && mode.getModeType() == eHuaShiGangModeType.A) {
            CrossActivityRankListModel model = new CrossActivityRankListModel(activityInfo.getActivityId(), false);
            model.setRankNum(100);
            return  model;
        }

        String key = HuaShiGangMgr.getKey(x, y);
        synchronized (monsterRankListModelMap) {
            if (!monsterRankListModelMap.containsKey(key)) {
                monsterRankListModelMap.put(key, new ConcurrentHashMap<>());
            }

            if (!monsterRankListModelMap.get(key).containsKey(monsterId)) {
                CrossActivityRankListModel model = new CrossActivityRankListModel(activityInfo.getActivityId(), false);
                model.setRankNum(100);
                monsterRankListModelMap.get(key).put(monsterId, model);
            }
        }
        return monsterRankListModelMap.get(key).get(monsterId);
    }

    /**
     * 初始化怪物榜单
     */
    public void initMonsterRankList() {
        for (Map.Entry<String, Map<Integer, Map<Long, HuaShiGangAttackRecord>>> entry : attackRecordMap.entrySet()) {
            List<Integer> list = StringUtils.stringToIntegerList(entry.getKey(), "-");
            int x = list.get(0);
            int y = list.get(1);

            // 普通怪物不生成排行榜 直接退出
            HuaShiGangMode mode = getModeByY(y);
            if (mode != null && mode.getModeType() == eHuaShiGangModeType.A) {
                continue;
            }

            for (Map.Entry<Integer, Map<Long, HuaShiGangAttackRecord>> monsterEntry : entry.getValue().entrySet()) {
                int monsterId = monsterEntry.getKey();
                CrossActivityRankListModel model = getMonsterRankListModel(x, y, monsterId);
                LinkedList<CrossUserRank> rankList = new LinkedList<>();
                for (HuaShiGangAttackRecord record : monsterEntry.getValue().values()) {
                    CrossUserRank rank = new CrossUserRank();
                    rank.setUserBaseInfo(record.getUserBaseInfo());
                    rank.setUserId(record.getUserId());
                    rank.setLastUpdateTime(record.getUpdateTime());
                    rank.setValue(BigInteger.valueOf(record.getDamage()));
                    rankList.add(rank);
                }
                if (rankList.size() > 0) {
                    model.setRankList(rankList);
                }
            }
        }
    }

    /**
     * 检查精英怪排行奖励是否完整
     */
    private void checkEliteRewardMap() {
        for (Map.Entry<String, Map<Integer, CrossActivityRankListModel>> entry : monsterRankListModelMap.entrySet()) {
            List<Integer> list = StringUtils.stringToIntegerList(entry.getKey(), "-");
            int x = list.get(0);
            int y = list.get(1);
            HuaShiGangMode mode = getModeByY(y);
            // 精英怪
            if (mode.getModeType() == eHuaShiGangModeType.B) {
                HuaShiGangMonsterData eliteMonster = huaShiGangMonsterDataMap.get(entry.getKey()).get(0);
                // 被击杀
                if (eliteMonster.getNowBlood() <= 0) {
                    // 检查实际奖励人数
                    int rewardCount = 0;
                    List<CrossUserRank> rankList = new ArrayList<>(entry.getValue().get(1).getRankList());
                    while (rewardCount < rankList.size() && rewardCount < newConfig.getEliteKillRankScore().size()) {
                        if (rankList.get(rewardCount).getValue().compareTo(BigInteger.ZERO) <= 0) {
                            break;
                        }
                        rewardCount++;
                    }
                    // 修复错误数据
                    if (!eliteRewardMap.containsKey(y)) {
                        eliteRewardMap.put(y, new ArrayList<>(3));
                    }
                    List<HuaShiGangEliteReward> eliteRewardList = eliteRewardMap.get(y);
                    if (eliteRewardList.size() != rewardCount) {
                        addEliteRewardList(y);
                    }
                }
            }
        }
    }

    /**
     * 添加精英怪排行奖励
     */
    private void addEliteRewardList(int y) {
        // 不是精英怪 或 精英怪未死
        HuaShiGangMode mode = getModeByY(y);
        HuaShiGangMonsterData monsterData = getHuaShiGangMonsterData(0, y, 1);
        if (mode == null || mode.getModeType() != eHuaShiGangModeType.B
                || monsterData == null || monsterData.getNowBlood() > 0) {
            return;
        }

        if (!eliteRewardMap.containsKey(y)) {
            eliteRewardMap.put(y, new ArrayList<>(newConfig.getEliteKillRankScore().size()));
        }
        List<HuaShiGangEliteReward> eliteRewardList = eliteRewardMap.get(y);
        List<CrossUserRank> rankList = new ArrayList<>(getMonsterRankListModel(0, y, 1).getRankList());
        synchronized (eliteRewardList) {
            // rankList用下标判断排名
            for (int i = 0; i < rankList.size() && i < newConfig.getEliteKillRankScore().size(); i++) {
                CrossUserRank crossUserRank = rankList.get(i);
                // 0伤害没奖励
                if (crossUserRank.getValue().compareTo(BigInteger.ZERO) <= 0) {
                    continue;
                }
                // 不存在该排名，添加一条
                final int realRank = i + 1;
                if (eliteRewardList.stream().noneMatch(item -> item.getRank() == realRank)) {
                    int eventId = getPoint(0, y).getEventId();
                    long totalScore = calcTotalScore(getHuaShiGangMonsterData(0, y, 1));
                    int ratio = newConfig.getEliteKillRankScore().get(i);
                    BigInteger count = new BigDecimal(totalScore).multiply(new BigDecimal(ratio)).divide(new BigDecimal(1000), BigDecimal.ROUND_UP).toBigInteger();

                    HuaShiGangEliteReward eliteReward = new HuaShiGangEliteReward();
                    eliteReward.setActivityId(activityInfo.getActivityId());
                    eliteReward.setY(y);
                    eliteReward.setRank(realRank);
                    eliteReward.setEventId(eventId);
                    eliteReward.setServerId(crossUserRank.getUserBaseInfo().getServerId());
                    eliteReward.setUserId(crossUserRank.getUserId());
                    eliteReward.setReward(PropertyHelper.parseGoodsToString(getHuaShiGangScoreId(), count));
                    eliteReward.setIsGetReward(false);
                    eliteReward.setInsertOption();
                    eliteRewardList.add(eliteReward);
                }
            }
        }
    }

    /**
     * 获取藏宝
     *
     * @param x
     * @param y
     * @param treasureId
     * @return
     */
    public HuaShiGangTreasure getTreasure(int x, int y, int treasureId) {
        String key = HuaShiGangMgr.getKey(x, y);
        List<HuaShiGangTreasure> treasureList = huaShiGangTreasureMap.get(key);
        if (treasureList == null) {
            return null;
        }

        for (HuaShiGangTreasure treasure : treasureList) {
            if (treasure.getTreasureId() == treasureId) {
                return treasure;
            }
        }
        return null;
    }

    public HuaShiGangTreasure getRandomTreasure(int x, int y) {
        String key = HuaShiGangMgr.getKey(x, y);
        List<HuaShiGangTreasure> treasureList = huaShiGangTreasureMap.get(key);
        if (treasureList == null) {
            return null;
        }

        List<HuaShiGangTreasure> list = new ArrayList<>();
        for (HuaShiGangTreasure treasure : treasureList) {
            if (treasure.getOpenTime() > 0) {
                continue;
            }
            list.add(treasure);
        }

        if (list.size() == 0) {
            return null;
        }

        return list.get(randomHelper.next(list.size()));
    }

    /**
     * 获取单个据点
     *
     * @param x
     * @param y
     * @return
     */
    public HuaShiGangStrongPoint getPoint(int x, int y) {
        if (y < 0) {
            return null;
        }
        int modeIndex = y / 3;

        if (huaShiGangModeList.size() <= modeIndex) {
            return null;
        }
        HuaShiGangMode huaShiGangMode = huaShiGangModeList.get(modeIndex);
        return huaShiGangMode.getPoint(x, y);
    }


    /**
     * 通过坐标定位模块
     *
     * @param y
     * @return
     */
    public HuaShiGangMode getModeByY(int y) {
        int modeIndex = y / 3;
        if (huaShiGangModeList.size() <= modeIndex || y < 0) {
            return null;
        }
        return huaShiGangModeList.get(modeIndex);
    }

    /**
     * 获取玩家锁
     *
     * @param userId
     * @return
     */
    public synchronized Object getUserLocker(long userId) {
        if (!userLocker.containsKey(userId)) {
            userLocker.put(userId, new Object());
        }
        return userLocker.get(userId);
    }

    /**
     * 重新加载配置
     */
    public void reloadConfig() {
        ActivityInfo info = ActivityBussiness.getActivityInfoByActivityId(activityInfo.getActivityId());
        if (info != null) {
            activityInfo = info;
            loadNewConfig(info.getActivityId());
            buildParam();
        }
    }

    public void repair() {

    }

    /**
     * 创建参数
     */
    public void buildParam() {
        huaShiGangActivityEventConfigMap = HuaShiGangActivityBusiness.getHuaShiGangActivityEventConfig(activityInfo.getActivityId()); // 从数据库中读取
        HuaShiGangLogic.parseEventConfigParam(huaShiGangActivityEventConfigMap.values());
        //构建模块事件MAP
        this.huaShiGangStageBigTypeEventsMap = HuaShiGangLogic.createStageBigTypeEventsMap(huaShiGangActivityEventConfigMap, newConfig.getStageTimeList());
    }

    public HuaShiGangActivity(ActivityInfo activityInfo) {
        userLocker = new ConcurrentHashMap<>();
        this.activityInfo = activityInfo;
        loadNewConfig(activityInfo.getActivityId());

        buildParam();
        // 从数据库加载活动相关所有数据..
        huaShiGangData = UserHuaShiGangBusiness.getHuaShiGangData(activityInfo.getActivityId());
        userDataMap = UserHuaShiGangBusiness.getHuaShiGangUserData(activityInfo.getActivityId()); // 玩家数据
        huaShiGangTreasureMap = UserHuaShiGangBusiness.getHuaShiGangTreasure(activityInfo.getActivityId()); // 宝箱记录
        huaShiGangMonsterDataMap = UserHuaShiGangBusiness.getHuaShiGangMonsterData(activityInfo.getActivityId()); // 怪物数据
        huaShiGangModeList = new ArrayList<>(); // 读取模块数据

        // 初始化怪物伤害排行
        attackRecordMap = UserHuaShiGangBusiness.getHuaShiGangAttackRecord(activityInfo.getActivityId()); // 攻击记录
        monsterRankListModelMap = new ConcurrentHashMap<>(); // 从攻击记录里获取
        initMonsterRankList();

        CrossActivityRankListModel model = new CrossActivityRankListModel(0, false);
        model.setRankNum(100);
        crossRankListModel = model;

        if (huaShiGangData == null) {
            HuaShiGangData data = new HuaShiGangData();
            data.setActivityId(activityInfo.getActivityId());
            data.setModeData("");
            data.setInsertOption();
            huaShiGangData = data;
        }

        if (StringUtils.isNullOrEmpty(huaShiGangData.getModeData())) {
            // 组装多个单元
            List<HuaShiGangMode> huaShiGangModeList = new ArrayList<>();
            int unitCount = calcUnitCount(0);
            for (int i = 0; i < unitCount; i++) {
                huaShiGangModeList.addAll(HuaShiGangMgr.getHuaShiGangUnit(getUnitModeCount(), huaShiGangModeList.size()));
            }

            HuaShiGangMgr.checkAndBuildModeConnection(huaShiGangModeList);

            this.huaShiGangModeList = huaShiGangModeList;
            huaShiGangData.setModeData(ZipUtils.gzip(JSON.toJSONString(this.huaShiGangModeList)));
        } else {
            this.huaShiGangModeList = JSONObject.parseArray(ZipUtils.gunzip(huaShiGangData.getModeData()), HuaShiGangMode.class);
        }

        // 检查所有模块看是否有模块数据缺失
        checkPointEvent();
        HuaShiGangMgr.printRoad(huaShiGangModeList);

        // 检查精英怪排行奖励（放在 怪物伤害排行、模块加载 之后）
        eliteRewardMap = UserHuaShiGangBusiness.getHuaShiGangEliteRewardMap(activityInfo.getActivityId());
        checkEliteRewardMap();

        for (HuaShiGangUserData huaShiGangUserData : userDataMap.values()) {
            // 得出最近的玩家
            changeLastHuaShiGangData(huaShiGangUserData);
            checkTreasureInPlayers(huaShiGangUserData);
        }
        checkKillBoss();


    }

    private void loadNewConfig(int activityId) {
        Map<String, ActivityConfig> configMap = ActivityBussiness.getActivityConfigMap(Collections.singletonList(activityId)).get(activityId);
        HuaShiGangNewConfig tmpConfig = new HuaShiGangNewConfig();
        tmpConfig.setScoreItemId(configMap.get(eActivityConfigType.EXCHANGE_SCORE_ITEM_ID.getName()).getIntValue());
        tmpConfig.setDispatchItemId(configMap.get(eActivityConfigType.HUASHIGUANG_DISPATCH_ITEM_ID.getName()).getIntValue());
        tmpConfig.setOperationTimeList(configMap.get(eActivityConfigType.HUASHIGUANG_OPERATION_TIME.getName()).getIntListValue("\\|")
                .stream().mapToLong(item -> item * DateHelper.MINUTE_MILLIONS).boxed().collect(Collectors.toList()));
        List<List<Integer>> stageTimeParam = new ArrayList<>();
        for (String str : StringUtils.stringToStringList(configMap.get(eActivityConfigType.HUASHIGUANG_STAGE_TIME.getName()).getValue(), "\\|")) {
            stageTimeParam.add(StringUtils.stringToIntegerList(str, ";"));
        }
        tmpConfig.setStageTimeList(stageTimeParam);
        tmpConfig.setDayUnitNum(configMap.get(eActivityConfigType.HUASHIGUANG_DAY_UNIT_NUM.getName()).getIntValue());
        tmpConfig.setUnitModeNum(configMap.get(eActivityConfigType.HUASHIGUANG_DAY_MODE_NUM.getName()).getIntValue());
        tmpConfig.setServerBaseHp(configMap.get(eActivityConfigType.HUASHIGUANG_ONE_SERVER_BASE_HP.getName()).getLongValue());
        List<List<Integer>> serverHpParam = new ArrayList<>();
        for (String str : StringUtils.stringToStringList(configMap.get(eActivityConfigType.HUASHIGUANG_SERVER_HP_ENLARGE.getName()).getValue(), "\\|")) {
            serverHpParam.add(StringUtils.stringToIntegerList(str, ";"));
        }
        tmpConfig.setServerHpEnlarge(serverHpParam);
        List<List<Integer>> monsterHpParam = new ArrayList<>();
        for (String str : StringUtils.stringToStringList(configMap.get(eActivityConfigType.HUASHIGUANG_MONSTER_HP_ENLARGE.getName()).getValue(), "\\|")) {
            monsterHpParam.add(StringUtils.stringToIntegerList(str, ";"));
        }
        tmpConfig.setMonsterHpEnlarge(monsterHpParam);
        List<List<Integer>> scoreCalcParam = new ArrayList<>();
        for (String str : StringUtils.stringToStringList(configMap.get(eActivityConfigType.HUASHIGUANG_SCORE_CALC_PARAM.getName()).getValue(), "\\|")) {
            scoreCalcParam.add(StringUtils.stringToIntegerList(str, ";"));
        }
        tmpConfig.setScoreCalcParam(scoreCalcParam);
        List<List<Integer>> pointMonsterNumParam = new ArrayList<>();
        for (String str : StringUtils.stringToStringList(configMap.get(eActivityConfigType.HUASHIGUANG_POINT_MONSTER_NUM.getName()).getValue(), "\\|")) {
            pointMonsterNumParam.add(StringUtils.stringToIntegerList(str, ";"));
        }
        tmpConfig.setPointMonsterNum(pointMonsterNumParam);
        tmpConfig.setNormalDispatchCost(configMap.get(eActivityConfigType.HUASHIGUANG_NORMAL_DISPATCH_COST_NUM.getName()).getIntListValue("\\|"));
        tmpConfig.setBossDispatchCost(configMap.get(eActivityConfigType.HUASHIGUANG_BOSS_DISPATCH_COST_NUM.getName()).getIntListValue("\\|"));
        tmpConfig.setHelpModeDistance(configMap.get(eActivityConfigType.HUASHIGUANG_TRIGGER_HELP_MODE_DISTANCE.getName()).getIntValue());
        List<List<Integer>> helpLengthParam = new ArrayList<>();
        for (String str : StringUtils.stringToStringList(configMap.get(eActivityConfigType.HUASHIGUANG_HELP_LENGTH.getName()).getValue(), "\\|")) {
            helpLengthParam.add(StringUtils.stringToIntegerList(str, ","));
        }
        tmpConfig.setHelpLength(helpLengthParam);
        tmpConfig.setHelpAddition(configMap.get(eActivityConfigType.HUASHIGUANG_HELP_ADDITION.getName()).getIntValue());
        if (configMap.containsKey(eActivityConfigType.HUASHIGUANG_DIG_PASS_BOX.getName())){
            tmpConfig.setDigPassBox(configMap.get(eActivityConfigType.HUASHIGUANG_DIG_PASS_BOX.getName()).getIntValue());
        }
        if (configMap.containsKey("HUASHIGUANG_DIG_PASS_BOX_CONTENT")) {
            List<List<Property>> list = PropertyHelper.parseNewStringToPropertyList(configMap.get("HUASHIGUANG_DIG_PASS_BOX_CONTENT").getValue());
            tmpConfig.setDigPassRewardList(list);
        }
        tmpConfig.setEliteKillRankScore(configMap.get(eActivityConfigType.HUASHIGUANG_ELITE_KILL_RANK_SCORE.getName()).getIntListValue(","));
        tmpConfig.setGoldKeyId(configMap.get(eActivityConfigType.HUASHIGUANG_GOLD_KEY_ID.getName()).getIntValue());
        tmpConfig.setDigItemId(configMap.get(eActivityConfigType.HUASHIGUANG_DIG_ITEM_ID.getName()).getIntValue());
        tmpConfig.setAttackDigItemGetParam(configMap.get(eActivityConfigType.HUASHIGUANG_DIG_ITEM_GET_PARAM.getName()).getIntListValue(";"));
        tmpConfig.setBossNoticeItemId(configMap.get(eActivityConfigType.HUASHIGUANG_KILL_BOSS_NOTICE_ITEM.getName()).getIntListValue("\\|"));
        tmpConfig.setRmbMallTime(configMap.get(eActivityConfigType.HUASHIGUANG_RMB_MALL_TIME.getName()).getLongValue() * DateHelper.MINUTE_MILLIONS);
        String hpParam1 = ActivityHelper.getActivityConfigValue(configMap, eActivityConfigType.HUASHIGUANG_BOSS_HP_PARAM_1);
        tmpConfig.setUserFloorEnlarge(StringUtils.stringToIntegerList(hpParam1, "\\|"));
        String hpParam2 = ActivityHelper.getActivityConfigValue(configMap, eActivityConfigType.HUASHIGUANG_BOSS_HP_PARAM_2);
        List<List<Integer>> bossHpEnlargeParam = new ArrayList<>();
        for (String str : StringUtils.stringToStringList(hpParam2, "#")) {
            bossHpEnlargeParam.add(StringUtils.stringToIntegerList(str, "\\|"));
        }
        tmpConfig.setBossHpEnlarge(bossHpEnlargeParam);
        if (configMap.containsKey(eActivityConfigType.HUASHIGUANG_STAGE_TWO_UNIT_NUM_LEAST.getName())) {
            tmpConfig.setStage2MinUnitCount(configMap.get(eActivityConfigType.HUASHIGUANG_STAGE_TWO_UNIT_NUM_LEAST.getName()).getIntValue());
        }
        String hpParam3 = ActivityHelper.getActivityConfigValue(configMap, eActivityConfigType.HUASHIGUANG_BOSS_HP_PARAM_3);
        tmpConfig.setBossHpParam3(StringUtils.stringToIntegerList(hpParam3, "\\|"));

        if (configMap.containsKey("AUTO_TEND_NUM")){
            String autoTendNum = configMap.get("AUTO_TEND_NUM").getValue();
            tmpConfig.setAutoOperateConfig(StringUtils.stringToIntegerList(autoTendNum, ";"));
        }else {
            tmpConfig.setAutoOperateConfig(new ArrayList<>());
        }
        newConfig = tmpConfig;
    }

    /**
     * 检查在宝库的玩家
     * @param huaShiGangUserData
     */
    public void checkTreasureInPlayers(HuaShiGangUserData huaShiGangUserData) {
        if (huaShiGangUserData.getY() < 0) {
            return;
        }
        synchronized (inTreasurePlayers) {
            HuaShiGangStrongPoint point = getPoint(huaShiGangUserData.getX(), huaShiGangUserData.getY());
            if (point != null) {
                HuaShiGangActivityEventConfig eventConfig = getHuaShiGangActivityEventConfigMap().get(point.getEventId());
                if (eventConfig != null) {
                    if (eventConfig.getEventType() == eHuaShiGangEventType.TREASURE_EVENT.getValue()) {
                        String key = HuaShiGangMgr.getKey(huaShiGangUserData.getX(), huaShiGangUserData.getY());
                        if (!inTreasurePlayers.containsKey(key)) {
                            inTreasurePlayers.put(key, new ConcurrentHashMap<>());
                        }
                        if (!inTreasurePlayers.get(key).containsKey(huaShiGangUserData.getServerId())) {
                            inTreasurePlayers.get(key).put(huaShiGangUserData.getServerId(), new HashSet<>());
                        }
                        inTreasurePlayers.get(key).get(huaShiGangUserData.getServerId()).add(huaShiGangUserData.getUserId());
                        HuaShiGangMgr.getLogger().info("in treasure notify, {} {} {}", key, huaShiGangUserData.getServerId(), huaShiGangUserData.getUserId());
                    }
                }
            }
        }
    }

    /**
     * 离开宝库
     * @param serverId
     * @param userId
     * @param x
     * @param y
     */
    public void checkTreasureOutPlayers(long serverId, long userId, int x, int y) {
        if (y < 0) {
            return;
        }
        synchronized (inTreasurePlayers) {
            HuaShiGangStrongPoint point = getPoint(x, y);
            if (point != null) {
                HuaShiGangActivityEventConfig eventConfig = getHuaShiGangActivityEventConfigMap().get(point.getEventId());
                if (eventConfig != null) {
                    if (eventConfig.getEventType() == eHuaShiGangEventType.TREASURE_EVENT.getValue()) {
                        String key = HuaShiGangMgr.getKey(x, y);
                        if (inTreasurePlayers.containsKey(key) && inTreasurePlayers.get(key).containsKey(serverId) && inTreasurePlayers.get(key).get(serverId).contains(userId)) {
                            inTreasurePlayers.get(key).get(serverId).remove(userId);
                            HuaShiGangMgr.getLogger().info("out treasure notify, {} {} {}", key, serverId, userId);
                        }
                    }
                }
            }
        }
    }

    /**
     * 获取某据点的玩家区服id信息
     * @param
     * @param
     * @return
     */
//    public List<Pair<Long, Long>> getTreasureInPlayerList(int x, int y) {
//        String key = HuaShiGangMgr.getKey(x, y);
//        synchronized (inTreasurePlayers) {
//            List<Pair<Long, Long>> list = new ArrayList<>();
//            if (inTreasurePlayers.containsKey(key)) {
//                for (Map.Entry<Long, Set<Long>> entry : inTreasurePlayers.get(key).entrySet()) {
//                    for (long userId : entry.getValue()) {
//                        Pair<Long, Long> pair = new Pair<>(entry.getKey(), userId);
//                        list.add(pair);
//                    }
//                }
//            }
//            return list;
//        }
//    }

    public void checkKillBoss() {
        HuaShiGangMode mode = huaShiGangModeList.get(huaShiGangModeList.size() - 1);
        if (mode.getModeType() == eHuaShiGangModeType.C) {
            HuaShiGangMonsterData huaShiGangMonsterData = getHuaShiGangRandomMonsterData(mode.getPoints()[0][0].getX(), mode.getPoints()[0][0].getY());
            if (huaShiGangMonsterData.getKillPlayer().getUserAliasId() > 0) {
                killBossUserBaseInfo = huaShiGangMonsterData.getKillPlayer();
            }
        }
    }

    /**
     * 替换最近的门客
     * @param huaShiGangUserData
     */
    public void changeLastHuaShiGangData(HuaShiGangUserData huaShiGangUserData) {
        if (killBossUserBaseInfo != null) {
            return;
        }
        if (huaShiGangUserData.getY() < 0) {
            return;
        }
        synchronized (lastHuaShiGangData) {
            if (lastHuaShiGangData.getUserId() == 0l) {
                lastHuaShiGangData = huaShiGangUserData;
                return;
            }

            if (huaShiGangUserData.getY() > lastHuaShiGangData.getY()) {
                lastHuaShiGangData = huaShiGangUserData;
                return;
            }

            // 层数相同的分数高的优先
            if (huaShiGangUserData.getY() == lastHuaShiGangData.getY()) {
                if (huaShiGangUserData.getAllScore() > lastHuaShiGangData.getAllScore()) {
                    lastHuaShiGangData = huaShiGangUserData;
                }
            }
        }
    }


//    /**
//     * 检查据点事件
//     */
//    public synchronized void checkPointEvent() {
//        Random random = new Random();
//        for (HuaShiGangMode huaShiGangMode : huaShiGangModeList) {
//            for (HuaShiGangStrongPoint[] huaShiGangStrongPoints : huaShiGangMode.getPoints()) {
//                for (HuaShiGangStrongPoint huaShiGangStrongPoint : huaShiGangStrongPoints) {
//                    if (huaShiGangStrongPoint != null) {
//                        if (huaShiGangStrongPoint.getEventId() == 0) {
//                            HuaShiGangActivityEventConfig event = null;
//                            HuaShiGangActivityEventConfig bossTreasureEvent = null; // 蔡京等boss宝库事件
//                            if (huaShiGangMode.getModeType() == eHuaShiGangModeType.A) {
//                                // 普通事件
//                                event = getEvent(eHuaShiGangEventType.getNormalEventTypeValues(), random, huaShiGangStrongPoint.getY());
//                            } else if (huaShiGangMode.getModeType() == eHuaShiGangModeType.B) {
//                                // 精英模块事件
//                                // 判断是精英还是藏宝模块
//                                if ((huaShiGangStrongPoint.getY() + 1) % 3 == 1) {
//                                    // 精英怪事件
//                                    event = getEvent(eHuaShiGangEventType.getCreamEventTypeValues(), random, huaShiGangStrongPoint.getY());
//                                } else {
//                                    // 藏宝事件
//                                    event = getEvent(eHuaShiGangEventType.getTreasureEventTypeValues(), random, huaShiGangStrongPoint.getY());
//                                }
//
//                            } else if (huaShiGangMode.getModeType() == eHuaShiGangModeType.C) {
//                                // BOSS事件
//                                event = getEvent(eHuaShiGangEventType.getBossEventTypeValues(), random, huaShiGangStrongPoint.getY());
//                                bossTreasureEvent = getEvent(eHuaShiGangEventType.getBossTreasureEventTypeValues(), random, huaShiGangStrongPoint.getY());
//                            } else if (huaShiGangMode.getModeType() == eHuaShiGangModeType.D) {
//                                // 中间boss模块
//                                if ((huaShiGangStrongPoint.getY() + 1) % 3 == 1) {
//                                    // 中间boss事件
//                                    event = getEvent(eHuaShiGangEventType.getBossEventTypeValues(), random, huaShiGangStrongPoint.getY());
//                                    bossTreasureEvent = getEvent(eHuaShiGangEventType.getBossTreasureEventTypeValues(), random, huaShiGangStrongPoint.getY());
//                                } else {
//                                    event = getEvent(eHuaShiGangEventType.getEmptyEventTypeValues(), random, huaShiGangStrongPoint.getY());
//                                }
//                            }
//
//                            if (eHuaShiGangEventType.isMonsterEvent(event.getEventType())) {
//                                // 生成怪物
//                                buildMonster(huaShiGangStrongPoint.getX(), huaShiGangStrongPoint.getY(), event);
//                            } else if (eHuaShiGangEventType.isTreasureEvent(event.getEventType())) {
//                                // 生成宝箱
//                                buildTreasure(huaShiGangStrongPoint.getX(), huaShiGangStrongPoint.getY(), event);
//                            }
//                            if (bossTreasureEvent != null) {
//                                // 生成boss宝箱
//                                buildTreasure(huaShiGangStrongPoint.getX(), huaShiGangStrongPoint.getY(), bossTreasureEvent);
//                            }
//
//                            huaShiGangStrongPoint.setEventId(event.getEventId());
//                            huaShiGangData.setModeData(ZipUtils.gzip(JSON.toJSONString(this.huaShiGangModeList)));
//                        } else {
//                            // 判断数据是否缺失
//                            HuaShiGangActivityEventConfig event = getHuaShiGangActivityEventConfigMap().get(huaShiGangStrongPoint.getEventId());
//                            if (eHuaShiGangEventType.isMonsterEvent(event.getEventType())) {
//                                // 生成怪物
//                                buildMonster(huaShiGangStrongPoint.getX(), huaShiGangStrongPoint.getY(), event);
//                            } else if (eHuaShiGangEventType.isTreasureEvent(event.getEventType())) {
//                                // 生成宝箱
//                                buildTreasure(huaShiGangStrongPoint.getX(), huaShiGangStrongPoint.getY(), event);
//                            }
//
//                        }
//                    }
//                }
//            }
//        }
//    }

    /**
     * 检查据点事件(6.5.0优化)
     */
    public synchronized void checkPointEvent() {
        long startTime = System.currentTimeMillis();
        Random random = new Random();
        for (HuaShiGangMode huaShiGangMode : huaShiGangModeList) {
            for (HuaShiGangStrongPoint[] huaShiGangStrongPoints : huaShiGangMode.getPoints()) {
                for (HuaShiGangStrongPoint huaShiGangStrongPoint : huaShiGangStrongPoints) {
                    if (huaShiGangStrongPoint != null) {
                        if (huaShiGangStrongPoint.getEventId() == 0) {
                            HuaShiGangActivityEventConfig event = null;
                            HuaShiGangActivityEventConfig bossTreasureEvent = null; // 蔡京等boss宝库事件
                            if (huaShiGangMode.getModeType() == eHuaShiGangModeType.A) {
                                // 普通事件
//                                event = getEvent(eHuaShiGangEventType.getNormalEventTypeValues(), random, huaShiGangStrongPoint.getY());
                                event = getEventNew(eHuaShiGangEventBigType.NORMAL_EVENT, random, huaShiGangStrongPoint.getY());
                            } else if (huaShiGangMode.getModeType() == eHuaShiGangModeType.B) {
                                // 精英模块事件
                                // 判断是精英还是藏宝模块
                                if ((huaShiGangStrongPoint.getY() + 1) % 3 == 1) {
                                    // 精英怪事件
//                                    event = getEvent(eHuaShiGangEventType.getCreamEventTypeValues(), random, huaShiGangStrongPoint.getY());
                                    event = getEventNew(eHuaShiGangEventBigType.CREAM_EVENT, random, huaShiGangStrongPoint.getY());
                                } else {
                                    // 藏宝事件
//                                    event = getEvent(eHuaShiGangEventType.getTreasureEventTypeValues(), random, huaShiGangStrongPoint.getY());
                                    event = getEventNew(eHuaShiGangEventBigType.TREASURE_EVENT, random, huaShiGangStrongPoint.getY());
                                }

                            } else if (huaShiGangMode.getModeType() == eHuaShiGangModeType.C) {
                                // BOSS事件
//                                event = getEvent(eHuaShiGangEventType.getBossEventTypeValues(), random, huaShiGangStrongPoint.getY());
//                                bossTreasureEvent = getEvent(eHuaShiGangEventType.getBossTreasureEventTypeValues(), random, huaShiGangStrongPoint.getY());
                                event = getEventNew(eHuaShiGangEventBigType.BOSS_EVENT, random, huaShiGangStrongPoint.getY());
                                bossTreasureEvent = getEventNew(eHuaShiGangEventBigType.BOSS_TREASURE_EVENT, random, huaShiGangStrongPoint.getY());
                            } else if (huaShiGangMode.getModeType() == eHuaShiGangModeType.D) {
                                // 中间boss模块
                                if ((huaShiGangStrongPoint.getY() + 1) % 3 == 1) {
                                    // 中间boss事件
//                                    event = getEvent(eHuaShiGangEventType.getBossEventTypeValues(), random, huaShiGangStrongPoint.getY());
//                                    bossTreasureEvent = getEvent(eHuaShiGangEventType.getBossTreasureEventTypeValues(), random, huaShiGangStrongPoint.getY());
                                    event = getEventNew(eHuaShiGangEventBigType.BOSS_EVENT, random, huaShiGangStrongPoint.getY());
                                    bossTreasureEvent = getEventNew(eHuaShiGangEventBigType.BOSS_TREASURE_EVENT, random, huaShiGangStrongPoint.getY());
                                } else {
//                                    event = getEvent(eHuaShiGangEventType.getEmptyEventTypeValues(), random, huaShiGangStrongPoint.getY());
                                    event = getEventNew(eHuaShiGangEventBigType.EMPTY_EVENT, random, huaShiGangStrongPoint.getY());
                                }
                            }

                            if (eHuaShiGangEventType.isMonsterEvent(event.getEventType())) {
                                // 生成怪物
                                buildMonster(huaShiGangStrongPoint.getX(), huaShiGangStrongPoint.getY(), event);
                            } else if (eHuaShiGangEventType.isTreasureEvent(event.getEventType())) {
                                // 生成宝箱
                                buildTreasure(huaShiGangStrongPoint.getX(), huaShiGangStrongPoint.getY(), event);
                            }
                            if (bossTreasureEvent != null) {
                                // 生成boss宝箱
                                buildTreasure(huaShiGangStrongPoint.getX(), huaShiGangStrongPoint.getY(), bossTreasureEvent);
                            }

                            huaShiGangStrongPoint.setEventId(event.getEventId());
                        } else {
                            // 判断数据是否缺失
                            HuaShiGangActivityEventConfig event = getHuaShiGangActivityEventConfigMap().get(huaShiGangStrongPoint.getEventId());
                            if (eHuaShiGangEventType.isMonsterEvent(event.getEventType())) {
                                // 生成怪物
                                buildMonster(huaShiGangStrongPoint.getX(), huaShiGangStrongPoint.getY(), event);
                            } else if (eHuaShiGangEventType.isTreasureEvent(event.getEventType())) {
                                // 生成宝箱
                                buildTreasure(huaShiGangStrongPoint.getX(), huaShiGangStrongPoint.getY(), event);
                            }

                        }
                    }
                }
            }
        }
        huaShiGangData.setModeData(ZipUtils.gzip(JSON.toJSONString(this.huaShiGangModeList)));
        long endTime = System.currentTimeMillis();
        logger.info("花石纲checkPointEvent耗时：{}", endTime - startTime);
    }

    /**
     * 是否已经全开
     *
     * @param x
     * @param y
     * @return
     */
    public boolean isTreasureAllOpened(int x, int y) {
        String key = HuaShiGangMgr.getKey(x, y);
        List<HuaShiGangTreasure> huaShiGangTreasureList = huaShiGangTreasureMap.get(key);
        if (huaShiGangTreasureList == null) {
            return true;
        }
        for (HuaShiGangTreasure treasure : huaShiGangTreasureList) {
            if (treasure.getOpenTime() == 0) {
                return false;
            }
        }
        return true;
    }

    /**
     * 生成藏宝事件的宝箱
     *
     * @param x
     * @param y
     * @param event
     */
    public synchronized void buildTreasure(int x, int y, HuaShiGangActivityEventConfig event) {
        String key = HuaShiGangMgr.getKey(x, y);
        if (huaShiGangTreasureMap.get(key) == null) {

            // 拿配置
            String tmpParamList = event.getParamList();
            if (event.getEventType() == eHuaShiGangEventType.BOSS_TREASURE_EVENT.getValue()) {
                tmpParamList = StringUtils.stringToStringList(event.getParamList(), "-").get(0);
            }
            List<String> stringParamList = StringUtils.stringToStringList(tmpParamList, "\\|");

            List<HuaShiGangTreasure> huaShiGangTreasureList = new ArrayList<>();
            for (String param : stringParamList) {
                List<String> s = StringUtils.stringToStringList(param, ";");
                boolean isGoodTreasure = s.get(1).equals("0") ? false : true;
                List<Integer> integerList = StringUtils.stringToIntegerList(s.get(0), "=");
                int num = integerList.get(2);
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.append(integerList.get(0));
                stringBuilder.append("=");
                stringBuilder.append(integerList.get(1));
                for (int i = 0; i < num; i++) {
                    HuaShiGangTreasure huaShiGangTreasure = new HuaShiGangTreasure();
                    huaShiGangTreasure.setActivityId(activityInfo.getActivityId());
                    huaShiGangTreasure.setPointKey(key);
                    huaShiGangTreasure.setGoodReward(isGoodTreasure);
                    huaShiGangTreasure.setOpenPlayer(new UserBaseInfo());
                    huaShiGangTreasure.setOpenTime(0);
                    huaShiGangTreasure.setReward(stringBuilder.toString());
                    huaShiGangTreasure.setInsertOption();
                    huaShiGangTreasureList.add(huaShiGangTreasure);
                }
            }
            Collections.shuffle(huaShiGangTreasureList);
            for (int i = 1; i <= huaShiGangTreasureList.size(); i++) {
                // 对宝藏进行编号
                huaShiGangTreasureList.get(i - 1).setTreasureId(i);
                HuaShiGangMgr.getLogger().info("build treasure. {},{}-{},{}", activityInfo.getActivityId(), x, y, huaShiGangTreasureList.get(i - 1).getReward());
            }
            huaShiGangTreasureMap.put(key, huaShiGangTreasureList);
        }
    }

    /**
     * 生成怪物
     *
     * @param x
     * @param y
     * @param event
     */
    public synchronized void buildMonster(int x, int y, HuaShiGangActivityEventConfig event) {
        String key = HuaShiGangMgr.getKey(x, y);

        long blood;
        if (event.getEventType() == eHuaShiGangEventType.NORMAL_MONSTER.getValue()) {
            blood = calcMonsterHp(event.getEventId());
        } else if (event.getEventType() == eHuaShiGangEventType.CREAM_MONSTER.getValue()) {
            blood = calcEliteMonsterHp(event.getEventId(), y);
        } else if (event.getEventType() == eHuaShiGangEventType.BOSS_MONSTER.getValue()) {
            blood = calcBossHp(event.getParamList(), y);
        } else {
            throw new RuntimeException("huashigang buildMonster error! activityId " +
                    activityInfo.getActivityId() + " eventId " + event.getEventId() + ".");
        }

        if (huaShiGangMonsterDataMap.get(key) == null) {
            // 生成怪物 分BOSS跟普通
            List<HuaShiGangMonsterData> monsterDataList = new ArrayList<>();
            int num = event.getEventType() == eHuaShiGangEventType.NORMAL_MONSTER.getValue() ? calcPointMonsterNum() : 1;
            for (int i = 1; i <= num; i++) {
                HuaShiGangMonsterData huaShiGangMonsterData = new HuaShiGangMonsterData(blood);
                huaShiGangMonsterData.setActivityId(activityInfo.getActivityId());
                huaShiGangMonsterData.setPointKey(key);
                huaShiGangMonsterData.setMonsterId(i);
                huaShiGangMonsterData.setKillPlayer(new UserBaseInfo());
                huaShiGangMonsterData.setKillUserId(0);
                huaShiGangMonsterData.setInsertOption();
                monsterDataList.add(huaShiGangMonsterData);
                HuaShiGangMgr.getLogger().info("build monster. {},{}-{},{}", activityInfo.getActivityId(), x, y, blood);
            }
            huaShiGangMonsterDataMap.put(key, monsterDataList);
        }
    }


    /**
     * 获取一个随机事件
     *
     * @param typeList
     * @return
     */
    public HuaShiGangActivityEventConfig getEvent(List<Integer> typeList, Random random, int y) {
        List<HuaShiGangActivityEventConfig> tempList = new ArrayList<>();
        List<Integer> weightList = new ArrayList<>();
        for (HuaShiGangActivityEventConfig huaShiGangActivityEventConfig : huaShiGangActivityEventConfigMap.values()) {
            if (typeList.contains(huaShiGangActivityEventConfig.getEventType())) {

                // 如果是怪物事件，还判断所处阶段是否符合
                if (eHuaShiGangEventType.isMonsterEvent(huaShiGangActivityEventConfig.getEventType())) {
                    if (getStage(y) != huaShiGangActivityEventConfig.getStage()) {
                        continue;
                    }
                }

                // Boss宝库事件也区分下阶段
                if (eHuaShiGangEventType.BOSS_TREASURE_EVENT.getValue() == huaShiGangActivityEventConfig.getEventType()) {
                    if (getStage(y) != huaShiGangActivityEventConfig.getStage()) {
                        continue;
                    }
                }

                tempList.add(huaShiGangActivityEventConfig);
                weightList.add(huaShiGangActivityEventConfig.getWeight());
            }
        }
        return tempList.get(RandomHelper.getRandomIndexByWeight(weightList, random));
    }

    /**
     * 获取一个随机事件（6.5.0优化）
     * @param bigType
     * @param random
     * @param y
     * @return
     */
    public HuaShiGangActivityEventConfig getEventNew(eHuaShiGangEventBigType bigType, Random random, int y) {
        //获取当前阶段
        int stage = getStage(y);
        //获取阶段的事件
        Map<Integer, HuaShiGangStageBigTypeEvents> bigTypeEventsMap = this.huaShiGangStageBigTypeEventsMap.get(stage);
        //随机出一个事件
        List<HuaShiGangActivityEventConfig> tempList = bigTypeEventsMap.get(bigType.getValue()).getEventList();
        List<Integer> weightList = bigTypeEventsMap.get(bigType.getValue()).getWeightList();
        return tempList.get(RandomHelper.getRandomIndexByWeight(weightList, random));
    }

    public ActivityInfo getActivityInfo() {
        return activityInfo;
    }

    public void setActivityInfo(ActivityInfo activityInfo) {
        this.activityInfo = activityInfo;
    }

    /**
     * 获取玩家数据
     *
     * @param serverId
     * @param userId
     * @return
     */
    public HuaShiGangUserData getUserData(long serverId, long userId) {
        synchronized (getUserLocker(userId)) {
            HuaShiGangUserData huaShiGangUserData = userDataMap.get(userId);
            if (huaShiGangUserData == null) {
                huaShiGangUserData = new HuaShiGangUserData(activityInfo.getActivityId(), serverId, userId);
                huaShiGangUserData.setInsertOption();
            }
            userDataMap.put(userId, huaShiGangUserData);

            if (!DateHelper.isToday(new Date(huaShiGangUserData.getResetUpdateTime()))) {
                for (HuaShiGangPatrons patrons : huaShiGangUserData.getPatronsMap().values()) {
                    patrons.setBatMap(new ConcurrentHashMap<>());
                    patrons.setNat(0);
                }
                huaShiGangUserData.setResetUpdateTime(System.currentTimeMillis());
            }
            return userDataMap.get(userId);
        }
    }

    /**
     * 选择下一个地点
     *  @param serverId
     * @param playerId
     * @param x
     * @param y
     * @param patronsList
     * @param goldenKeyNum
     * @param userBaseInfo
     */
    public int chooseNextPoint(long serverId, long playerId, int x, int y, List<Integer> patronsList, int goldenKeyNum, UserBaseInfo userBaseInfo, long totalAbility) {
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        huaShiGangUserData.setUserBaseInfo(userBaseInfo);
        huaShiGangUserData.setTotalAbility(totalAbility);
        HuaShiGangStrongPoint newPoint = getPoint(x, y);
        if (newPoint == null) {
            return GameErrorCode.E_HUA_SHI_GANG_POINT_ERROR;
        }
        synchronized (huaShiGangUserData) {
            if (huaShiGangUserData.getX() == -1 && huaShiGangUserData.getY() == -1) {
                // 如果是初始状态的话必定可以选择下一关 并且y=0表示是第一层 自由选择路线
                if (y != 0) {
                    return GameErrorCode.E_HUA_SHI_GANG_POINT_ERROR;
                }

                choosePoint(huaShiGangUserData, x, y, newPoint, patronsList, goldenKeyNum);
            } else {
                // 其他有事件的情况判断是否可以马上进入到下一关
                HuaShiGangStrongPoint nowPoint = getPoint(huaShiGangUserData.getX(), huaShiGangUserData.getY());
                if (nowPoint == null) {
                    return GameErrorCode.E_HUA_SHI_GANG_POINT_USER_POINT_ERROR;
                }


                if (!isInNextPoint(nowPoint, newPoint)) {
                    return GameErrorCode.E_HUA_SHI_GANG_POINT_ERROR;
                }

                if (!huaShiGangUserData.isFinish()) {
                    return GameErrorCode.E_HUA_SHI_GANG_EVENT_NOT_COMPLETE;
//                    // 不能结束
//                    int eventId = nowPoint.getEventId();
//                    HuaShiGangActivityEventConfig config = huaShiGangActivityEventConfigMap.get(eventId);
//                    if (eHuaShiGangEventType.isMonsterEvent(config.getEventType())) {
//                        HuaShiGangMonsterData monster = getHuaShiGangMonsterData(huaShiGangUserData.getX(), huaShiGangUserData.getY(), huaShiGangUserData.getMonsterId());
//                        if (monster.getNowBlood() > 0) {
//                            //怪物未被击败
//                            return GameErrorCode.E_HUA_SHI_GAG_POINT_MONSTER_IS_ALIVE;
//                        }
//                    } else if (eHuaShiGangEventType.isTradeEvent(config.getEventType())) {
//
//                    } else if (eHuaShiGangEventType.isTreasureEvent(config.getEventType())) {
//                        // 判断是否还有藏宝没开 一样可以选择跳过
//                        if (!isTreasureAllOpened(nowPoint.getX(), nowPoint.getY())) {
//                            return GameErrorCode.E_HUA_SHI_GAG_POINT_HAS_TREASURE;
//                        }
//                    } else if (eHuaShiGangEventType.BOX_EVENT.getValue() == config.getEventType()) {
//
//                    } else if (eHuaShiGangEventType.SHOP_EVENT.getValue() == config.getEventType()) {
//
//                    } else if (eHuaShiGangEventType.UNEXPECTED_EVENT.getValue() == config.getEventType()) {
//                        return GameErrorCode.E_HUA_SHI_GAG_POINT_NOT_CHOOSE_PATRONS;
//                    }
                }

                choosePoint(huaShiGangUserData, x, y, newPoint, patronsList, goldenKeyNum);
            }
        }

        synchronized (this) {
            checkHelperMonster(serverId, playerId, huaShiGangUserData.getY());
            checkCreateBoss(huaShiGangUserData.getY());
        }

        return 0;
    }

    /**
     * 判断是否需要援兵
     *
     * @param y
     */
    public synchronized void checkHelperMonster(long serverId, long playerId, int y) {

        // 最终BOSS出现，不需要援兵
        // 中间BOSS出现，不需要援兵，等被击杀时会生成后续路径
        HuaShiGangMode mode = huaShiGangModeList.get(huaShiGangModeList.size() - 1);
        if (mode.getModeType() == eHuaShiGangModeType.C || mode.getModeType() == eHuaShiGangModeType.D) {
            return;
        }

        // 是否到触发援兵的距离
        int maxY = mode.getPoints()[0][2].getY();
        int needHelpY = maxY + 1 - newConfig.getHelpModeDistance() * 3;
        if (y < needHelpY) {
            return;
        }

        // 是否在触发援兵的时间内
        int createBossNum = huaShiGangData.getBossYList().size();
        if (createBossNum >= newConfig.getStageTimeList().size()) {
            return; // boss全部生成完了
        }
        List<Integer> nextBossConfig = newConfig.getStageTimeList().get(createBossNum);
        long nextBossTime = nextBossConfig.get(1) * DateHelper.MINUTE_MILLIONS + activityInfo.getBeginShowTime() * 1000L;
        long now = System.currentTimeMillis();
        if (now >= nextBossTime) {
            return; // 这只boss不用再援兵了
        }

        // 判断触发几波
        int hour = BigDecimal.valueOf(nextBossTime - now).divide(BigDecimal.valueOf(DateHelper.HOUR_MILLIONS), 0, BigDecimal.ROUND_DOWN).intValue();
        int unitNum = 0;
        for (List<Integer> list : newConfig.getHelpLength()) {
            if (hour >= list.get(0)) {
                unitNum = list.get(1);
                break;
            }
        }
        if (unitNum <= 0) {
            return;
        }

        int stage = getStage(y);

        // 生成援兵
        List<HuaShiGangMode> newModeList = new ArrayList<>();
        for (int i = 0; i < unitNum; i++) {
            newModeList.addAll(HuaShiGangMgr.getHuaShiGangUnit(getUnitModeCount(), newModeList.size() + huaShiGangModeList.size()));
        }
        huaShiGangModeList.addAll(newModeList);
        HuaShiGangMgr.checkAndBuildModeConnection(huaShiGangModeList);
        checkPointEvent();
        huaShiGangData.setModeData(ZipUtils.gzip(JSON.toJSONString(this.huaShiGangModeList)));
        notifySystemMsg(serverId, playerId, eHuaShiGangMessageType.HELPER_MONSTER.getValue() + GameConfig.TALK_SEPARATOR + (newModeList.size() * 3 - unitNum) + GameConfig.TALK_SEPARATOR + stage);
        HuaShiGangMgr.getLogger().info("add Helper. {} {}", activityInfo.getActivityId(), newModeList.size());
        CrossAutoLogMgr.add(new HuaShiGangHelperLog(serverId, playerId, activityInfo.getActivityId(), activityInfo.getChildType(), newModeList.size() * 3 - unitNum, System.currentTimeMillis()));
    }

    /**
     * 判断是否需要生成boss
     *
     * @param y
     */
    public synchronized void checkCreateBoss(int y) {

        // 判断boss是不是生成完了
        HuaShiGangMode mode = huaShiGangModeList.get(huaShiGangModeList.size() - 1);
        if (mode.getModeType() == eHuaShiGangModeType.C) {
            return;
        }

        // 判断是否走到最后一模块
        int maxY = mode.getPoints()[0][2].getY();
        if (y < maxY) {
            return;
        }

        // 看看是不是都生成了
        List<Integer> bossYList = huaShiGangData.getBossYList();
        for (int i = 0; i < bossYList.size(); i++) {
            if (y <= bossYList.get(i)) {
                return; // 后面已经有boss了
            }
        }

        // 生成BOSS
        boolean isLastBoss = bossYList.size() >= newConfig.getStageTimeList().size() - 1; // 判断是否是最后一只boss
        List<HuaShiGangMode> modeList = new ArrayList<>();
        modeList.add(isLastBoss ? HuaShiGangBuildMode.getCMode() : HuaShiGangBuildMode.getDMode());
        HuaShiGangMgr.buildUnitInnerFloor(modeList, huaShiGangModeList.size() * 3);
        this.huaShiGangModeList.addAll(modeList);
        HuaShiGangMgr.checkAndBuildModeConnection(huaShiGangModeList);
        checkPointEvent();
        huaShiGangData.setModeData(ZipUtils.gzip(JSON.toJSONString(this.huaShiGangModeList)));
        HuaShiGangMgr.getLogger().info("add Boss. {}", activityInfo.getActivityId());

        // 记录boss位置
        int bossY = isLastBoss ? huaShiGangModeList.get(huaShiGangModeList.size() - 1).getPoints()[0][0].getY() :
                huaShiGangModeList.get(huaShiGangModeList.size() - 1).getPoints()[0][0].getY();
        ArrayList<Integer> yList = new ArrayList<>(huaShiGangData.getBossYList());
        yList.add(bossY);
        huaShiGangData.setBossYList(yList);
    }

    /**
     * 生成阶段boss后路径
     */
    public synchronized void createNextStageUnit(int curY) {

        // 检查下有没有下只boss（调用到这个方法时正常都会有下只boss）
        int createBossNum = huaShiGangData.getBossYList().size();
        if (createBossNum >= newConfig.getStageTimeList().size()) {
            return;
        }

        // 下阶段初始单元数
        int unitCount = 0;
        List<Integer> nextBossConfig = newConfig.getStageTimeList().get(createBossNum);
        long nextBossTime = nextBossConfig.get(1) * DateHelper.MINUTE_MILLIONS + activityInfo.getBeginShowTime() * 1000L;
        long now = System.currentTimeMillis();
        if (now < nextBossTime) { // 还没到下只boss出现时间，才有援兵配置
            int hour = BigDecimal.valueOf(nextBossTime - now).divide(BigDecimal.valueOf(DateHelper.HOUR_MILLIONS), 0, BigDecimal.ROUND_DOWN).intValue();
            // 遍历配置，找生成单元数
            for (List<Integer> list : newConfig.getHelpLength()) {
                if (hour >= list.get(0)) {
                    unitCount = list.get(1);
                    break;
                }
            }
        }

        // 保底单元数判断
        int minUnitCount = newConfig.getStage2MinUnitCount();
        if (unitCount < minUnitCount) {
            unitCount = minUnitCount;
        }

        // 按援兵逻辑生成下一阶段初始单元
        List<HuaShiGangMode> newModeList = new ArrayList<>();
        for (int i = 0; i < unitCount; i++) {
            newModeList.addAll(HuaShiGangMgr.getHuaShiGangUnit(getUnitModeCount(), newModeList.size() + huaShiGangModeList.size()));
        }
        huaShiGangModeList.addAll(newModeList);
        HuaShiGangMgr.checkAndBuildModeConnection(huaShiGangModeList);
        checkPointEvent();
        huaShiGangData.setModeData(ZipUtils.gzip(JSON.toJSONString(this.huaShiGangModeList)));
        HuaShiGangMgr.getLogger().info("next stage Helper. {} {}", activityInfo.getActivityId(), newModeList.size());

        // 检查下是否boss避免没有生成路径
        checkCreateBoss(curY);
    }

    /**
     * 推送消息
     *
     * @param serverId
     * @param playerId
     * @param content
     */
    public void notifySystemMsg(long serverId, long playerId, String content) {
        HuaShiGangProto.HuaShiGangSystemNotify.Builder builder = HuaShiGangProto.HuaShiGangSystemNotify.newBuilder();
        builder.setActivityId(activityInfo.getActivityId());
        builder.setContent(content);
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(GameProtocol.S_HUA_SHI_GANG_NOTIFY_SYSTEM_MSG, builder));
    }

    /**
     * 判断是否在下一个点
     *
     * @param nowPoint
     * @param newPoint
     */
    public boolean isInNextPoint(HuaShiGangStrongPoint nowPoint, HuaShiGangStrongPoint newPoint) {
        for (Point point : nowPoint.getNextList()) {
            if (point.getX() == newPoint.getX() && point.getY() == newPoint.getY()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取随机怪物
     *
     * @param x
     * @param y
     * @return
     */
    public HuaShiGangMonsterData getHuaShiGangRandomMonsterData(int x, int y) {
        String key = HuaShiGangMgr.getKey(x, y);
        List<HuaShiGangMonsterData> monsterDataList = new ArrayList<>();
        List<HuaShiGangMonsterData> dataList = huaShiGangMonsterDataMap.get(key);
        if (dataList == null) {
            return null;
        }
        for (HuaShiGangMonsterData huaShiGangMonsterData : dataList) {
            if (huaShiGangMonsterData.getNowBlood() > 0) {
                monsterDataList.add(huaShiGangMonsterData);
            }
        }
        if (monsterDataList.size() == 0) {
            monsterDataList.addAll(huaShiGangMonsterDataMap.get(key));
        }

        return monsterDataList.get(randomHelper.next(monsterDataList.size()));

    }

    /**
     * 获取怪物
     *
     * @param x
     * @param y
     * @return
     */
    public HuaShiGangMonsterData getHuaShiGangMonsterData(int x, int y, int monsterId) {
        String key = HuaShiGangMgr.getKey(x, y);
        if (!huaShiGangMonsterDataMap.containsKey(key)) {
            return null;
        }
        for (HuaShiGangMonsterData huaShiGangMonsterData : huaShiGangMonsterDataMap.get(key)) {
            if (huaShiGangMonsterData.getMonsterId() == monsterId) {
                return huaShiGangMonsterData;
            }
        }
        return null;
    }

    /**
     * 选择了坐标
     *
     * @param huaShiGangUserData
     * @param x
     * @param y
     * @param point
     * @param patronsList
     */
    public void choosePoint(HuaShiGangUserData huaShiGangUserData, int x, int y, HuaShiGangStrongPoint point, List<Integer> patronsList, int goldenKeyNum) {
        huaShiGangUserData.reset(x, y);
        // 产生新事件
        int eventId = point.getEventId();
        HuaShiGangActivityEventConfig config = huaShiGangActivityEventConfigMap.get(eventId);
        synchronized (point) {
            if (eHuaShiGangEventType.isMonsterEvent(config.getEventType())) {
                // 怪物事件 从怪物数据那边随机一个boss出来
                HuaShiGangMonsterData huaShiGangMonsterData = getHuaShiGangRandomMonsterData(x, y);
                huaShiGangUserData.setFinish(false);
                huaShiGangUserData.setMonsterId(huaShiGangMonsterData.getMonsterId());

                if (huaShiGangMonsterData.getNowBlood() > 0) {
                    addAttackRecord(huaShiGangUserData.getX(), huaShiGangUserData.getY(), huaShiGangMonsterData.getMonsterId(), huaShiGangUserData.getUserId(), huaShiGangUserData.getServerId(), huaShiGangUserData.getUserBaseInfo(), 0);
                }
            } else if (eHuaShiGangEventType.isTradeEvent(config.getEventType())) {
                // 贸易事件
                huaShiGangUserData.setFinish(false);
            } else if (eHuaShiGangEventType.isTreasureEvent(config.getEventType())) {
                // 宝藏事件 玩家选择宝箱 判断是否还有宝藏来决定是否finish
                huaShiGangUserData.setFinish(false);
                checkTreasureInPlayers(huaShiGangUserData);
            } else if (eHuaShiGangEventType.BOX_EVENT.getValue() == config.getEventType()) {
                // 宝箱事件 生成一个宝箱返回给玩家 根据黄金宝箱钥匙判断给啥
                boolean goldenEvent = false;
                for (HuaShiGangActivityEventConfig eventConfig : huaShiGangActivityEventConfigMap.values()) {
                    if (eventConfig.getEventType() == eHuaShiGangEventType.BOX_EVENT.getValue()) {
                        if (eventConfig.getOpenCostKeyId() == getHuaShiGangGoldKeyId()) {
                            // 判断是黄金宝箱 查看玩家余量 如果宝箱钥匙>黄金宝箱剩余数量 则必定给黄金宝箱
                            int goldenBoxNum = 0;
                            if (huaShiGangUserData.getBoxMap().containsKey(eventConfig.getEventId())) {
                                goldenBoxNum = huaShiGangUserData.getBoxMap().get(eventConfig.getEventId());
                            }
                            if (goldenKeyNum > goldenBoxNum) {
                                if (!huaShiGangUserData.getBoxMap().containsKey(eventConfig.getEventId())) {
                                    huaShiGangUserData.getBoxMap().put(eventConfig.getEventId(), 0);
                                }
                                huaShiGangUserData.getBoxMap().put(eventConfig.getEventId(), huaShiGangUserData.getBoxMap().get(eventConfig.getEventId()) + 1);
                                goldenEvent = true;
                                huaShiGangUserData.setBoxEventId(eventConfig.getEventId());
                            }
                            break;
                        }
                    }
                }
                if (!goldenEvent) {
                    // 如果没有生成黄金宝箱事件的话 则根据概率随机生成一种宝箱
                    List<Integer> typeList = new ArrayList<>();
                    typeList.add(eHuaShiGangEventType.BOX_EVENT.getValue());
                    HuaShiGangActivityEventConfig eventConfig = getEvent(typeList, new Random(), point.getY());
                    if (!huaShiGangUserData.getBoxMap().containsKey(eventConfig.getEventId())) {
                        huaShiGangUserData.getBoxMap().put(eventConfig.getEventId(), 0);
                    }
                    huaShiGangUserData.getBoxMap().put(eventConfig.getEventId(), huaShiGangUserData.getBoxMap().get(eventConfig.getEventId()) + 1);
                    huaShiGangUserData.setBoxEventId(eventConfig.getEventId());
                }

                huaShiGangUserData.setFinish(false);
            } else if (eHuaShiGangEventType.SHOP_EVENT.getValue() == config.getEventType()) {
                // 商店事件
                huaShiGangUserData.setFinish(false);
                // 下发消息给玩家 表示有一个商店事件
                HuaShiGangProto.HuaShiGangNotifyGameServerShop.Builder builder = HuaShiGangProto.HuaShiGangNotifyGameServerShop.newBuilder();
                builder.setStat(0);
                MessageHelper.sendPacket(huaShiGangUserData.getServerId(), huaShiGangUserData.getUserId(), YanQuMessageUtils.buildMessage(GameProtocol.S_HUA_SHI_GANG_NOTIFY_SHOP_FROM_CROSS, builder));
            } else if (eHuaShiGangEventType.UNEXPECTED_EVENT.getValue() == config.getEventType()) {
                // 意外事件
                List<Integer> indexList = RandomHelper.getDifferentRandomNum(patronsList.size(), 3);
                for (int index : indexList) {
                    huaShiGangUserData.getRandomPatronsId().add(patronsList.get(index));
                }
                huaShiGangUserData.setFinish(false);
            }

            HuaShiGangProto.HuaShiGangEventLog.Builder builder = HuaShiGangPb.getHuaShiGangEventLogPb(activityInfo.getActivityId(), config.getEventType(), config.getEventId());
            MessageHelper.sendPacket(huaShiGangUserData.getServerId(), huaShiGangUserData.getUserId(), YanQuMessageUtils.buildMessage(GameProtocol.S_HUA_SHI_GANG_NOTIFY_EVENT_LOG, builder));
        }



        changeLastHuaShiGangData(huaShiGangUserData);
    }

    /**
     * 选择意外事件门客增益
     *
     * @param serverId
     * @param playerId
     * @param index
     * @return
     */
    public int chooseUnexpectedPatrons(long serverId, long playerId, int index) {
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        synchronized (huaShiGangUserData) {
            if (huaShiGangUserData.isFinish()) {
                return GameErrorCode.E_HUA_SHI_GANG_HAS_CHOOSE_PATRONS;
            }
            HuaShiGangStrongPoint point = getPoint(huaShiGangUserData.getX(), huaShiGangUserData.getY());
            if (point == null) {
                return GameErrorCode.E_HUA_SHI_GANG_POINT_ERROR;
            }

            HuaShiGangActivityEventConfig config = huaShiGangActivityEventConfigMap.get(point.getEventId());
            if (config.getEventType() != eHuaShiGangEventType.UNEXPECTED_EVENT.getValue()) {
                return GameErrorCode.E_HUA_SHI_GANG_EVENT_ERROR;
            }

            if (huaShiGangUserData.getRandomPatronsId().size() <= index) {
                return GameErrorCode.E_HUA_SHI_GANG_CHOOSE_PATRONS_ERROR;
            }

            int patronsId = huaShiGangUserData.getRandomPatronsId().get(index);
            huaShiGangUserData.initPatrons(patronsId);
            HuaShiGangPatrons huaShiGangPatrons = huaShiGangUserData.getPatronsMap().get(patronsId);
            huaShiGangPatrons.setAddition(huaShiGangPatrons.getAddition() + config.getAddition());
            huaShiGangUserData.setFinish(true);
            huaShiGangUserData.setUpdateOption();

            HuaShiGangProto.HuaShiGangNotifyChoosePatronsLog.Builder builder = HuaShiGangPb.getHuaShiGangPatronsLogPb(activityInfo.getActivityId(), patronsId, huaShiGangPatrons.getAddition() - config.getAddition(), config.getAddition(), huaShiGangPatrons.getAddition());
            MessageHelper.sendPacket(huaShiGangUserData.getServerId(), huaShiGangUserData.getUserId(), YanQuMessageUtils.buildMessage(GameProtocol.S_HUA_SHI_GANG_NOTIFY_CHOOSE_PATRONS_LOG, builder));
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(ClientProtocol.U_HUA_SHI_GANG_USER_DATA_NOTIFY, HuaShiGangMgr.getHuaShiUserDataGangRespMsg(activityInfo.getActivityId(), serverId, playerId)));
        }
        return 0;
    }

    /**
     * 打开宝箱
     *
     * @param serverId
     * @param playerId
     * @param boxId
     * @return
     */
    public ReturnData openBox(long serverId, long playerId, int boxId, int num) {
        StringBuilder rewardStringBuilder = new StringBuilder();
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        synchronized (huaShiGangUserData) {
            if (huaShiGangUserData.getBoxMap().get(boxId) == null || huaShiGangUserData.getBoxMap().get(boxId) < num) {
                return new ReturnData(GameErrorCode.E_HUA_SHI_GANG_NOT_BOX);
            }
            HuaShiGangStrongPoint point = getPoint(huaShiGangUserData.getX(), huaShiGangUserData.getY());
            HuaShiGangActivityEventConfig config = huaShiGangActivityEventConfigMap.get(boxId);
            if (config.getEventType() != eHuaShiGangEventType.BOX_EVENT.getValue()) {
                return new ReturnData(GameErrorCode.E_HUA_SHI_GANG_EVENT_ERROR);
            }

//            List<Integer> indexList = RandomHelper.getDifferentRandomNum(config.getBoxRewardList().size(), config.getBoxRewardNum());
//
//            for (int index : indexList) {
//                rewardStringBuilder.append(config.getBoxRewardList().get(index));
//                rewardStringBuilder.append(";");
//            }

            // 批量开宝箱
            Property rewardProp = PropertyHelper.parseStringToProperty(config.getRewards());
            rewardProp.rideProperty(num);
            String rewardStr = PropertyHelper.parsePropertyToString(rewardProp);

            rewardStringBuilder.append(rewardStr);
            huaShiGangUserData.getBoxMap().put(boxId, huaShiGangUserData.getBoxMap().get(boxId) - num);
            if (point != null && huaShiGangActivityEventConfigMap.get(point.getEventId()).getEventType() == eHuaShiGangEventType.BOX_EVENT.getValue()) {
                // 如果当前据点是箱子据点的话 把当前时间设置为已完成
                huaShiGangUserData.setFinish(true);
            }

            huaShiGangUserData.setUpdateOption();
//            notifySystemMsg(serverId, playerId, eHuaShiGangMessageType.BOX_OPEN.getValue() + GameConfig.TALK_SEPARATOR + config.getEventId() + GameConfig.TALK_SEPARATOR + rewardStringBuilder.toString());
        }
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(ClientProtocol.U_HUA_SHI_GANG_USER_DATA_NOTIFY, HuaShiGangMgr.getHuaShiUserDataGangRespMsg(activityInfo.getActivityId(), serverId, playerId)));
        return new ReturnData(0, rewardStringBuilder.toString());
    }

    /**
     * 解锁交通工具
     * @param serverId
     * @param playerId
     * @param transportId
     * @param builder
     */
    public void unLockTransport(long serverId, long playerId, int transportId, HuaShiGangProto.UnLockTransportRespToGameServerMsg.Builder builder) {
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        synchronized (huaShiGangUserData) {
            //判断是否已经解锁该交通工具
            if (huaShiGangUserData.getTransportList().contains(transportId)) {
                builder.setRet(GameErrorCode.E_HUA_SHI_GANG_TRANSPORT_ALREADY_UNLOCK);
                return;
            }
            //可以解锁
            huaShiGangUserData.getTransportList().add(transportId);
            huaShiGangUserData.setUpdateOption();
            //7.2优化,给玩家自动开启开关
            List<Integer> openSwitchList = new ArrayList<>(newConfig.getAutoOperateConfig());
            updateOpenSwitch(serverId, playerId, openSwitchList);

            builder.setRet(0);
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(ClientProtocol.U_HUA_SHI_GANG_USER_DATA_NOTIFY, HuaShiGangMgr.getHuaShiUserDataGangRespMsg(activityInfo.getActivityId(), serverId, playerId)));
        }
    }

    /**
     * 更换交通工具
     *  @param serverId
     * @param playerId
     * @param transportId
     * @param builder
     */
    public void changeTransport(long serverId, long playerId, int transportId, HuaShiGangProto.ChangeTransportRespMsg.Builder builder) {
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        synchronized (huaShiGangUserData) {
            // 0 是换回默认的 不是0的话 判断是否解锁该交通工具
            if (transportId != 0 && !huaShiGangUserData.getTransportList().contains(transportId)) {
                builder.setRet(GameErrorCode.E_HUA_SHI_GANG_TRANSPORT_LOCK);
                return;
            }
            // 更换
            huaShiGangUserData.setTransportId(transportId);
            builder.setRet(0);
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(ClientProtocol.U_HUA_SHI_GANG_USER_DATA_NOTIFY, HuaShiGangMgr.getHuaShiUserDataGangRespMsg(activityInfo.getActivityId(), serverId, playerId)));
        }
    }

    /**
     * 贸易
     *
     * @param serverId
     * @param playerId
     * @param eventId
     * @return
     */
    public int trade(long serverId, long playerId, int eventId) {
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        synchronized (huaShiGangUserData) {
            if (huaShiGangUserData.isFinish()) {
                return GameErrorCode.E_HUA_SHI_GANG_HAS_TRADE;
            }

            HuaShiGangStrongPoint point = getPoint(huaShiGangUserData.getX(), huaShiGangUserData.getY());
            if (eventId != point.getEventId()) {
                return GameErrorCode.E_HUA_SHI_GANG_EVENT_ERROR;
            }

            if (huaShiGangActivityEventConfigMap.get(eventId).getEventType() != eHuaShiGangEventType.TRADE_EVENT.getValue()) {
                return GameErrorCode.E_HUA_SHI_GANG_EVENT_ERROR;
            }

            huaShiGangUserData.setFinish(true);
        }
        HuaShiGangProto.TradeExchangeFromCross.Builder builder = HuaShiGangProto.TradeExchangeFromCross.newBuilder();
        builder.setActivityId(activityInfo.getActivityId());
        builder.setEventId(eventId);
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(GameProtocol.S_HUA_SHI_GANG_TRADE_FROM_CROSS, builder));
        return 0;
    }

    /**
     * 获取藏宝列表
     *
     * @param serverId
     * @param playerId
     * @return
     */
    public int getTreasureList(long serverId, long playerId) {
        HuaShiGangProto.GetTreasureListMsgRespMsg.Builder builder = null;
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        synchronized (huaShiGangUserData) {
            if (huaShiGangUserData.isFinish()) {
                return GameErrorCode.E_HUA_SHI_GANG_EVENT_HAS_COMPLETE;
            }

            HuaShiGangStrongPoint point = getPoint(huaShiGangUserData.getX(), huaShiGangUserData.getY());
            if (point == null) {
                return GameErrorCode.E_HUA_SHI_GANG_POINT_ERROR;
            }
            synchronized (point) {
                List<HuaShiGangTreasure> treasureList = huaShiGangTreasureMap.get(HuaShiGangMgr.getKey(huaShiGangUserData.getX(), huaShiGangUserData.getY()));
                if (treasureList == null) {
                    return GameErrorCode.E_HUA_SHI_GANG_EVENT_ERROR;
                }


                builder = HuaShiGangPb.getHuaShiGangTreasureListPb(treasureList);
            }
        }

        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(ClientProtocol.U_HUA_SHI_GANG_GET_TREASURE_LIST, builder));
        return 0;
    }

    /**
     * 打开藏宝
     *
     * @param serverId
     * @param playerId
     * @param treasureId
     * @param userBaseInfo
     * @return
     */
    public int openTreasure(long serverId, long playerId, int treasureId, UserBaseInfo userBaseInfo) {
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        HuaShiGangProto.OpenTreasureFromCross.Builder builder = null;
        synchronized (huaShiGangUserData) {
            if (huaShiGangUserData.isFinish()) {
                return GameErrorCode.E_HUA_SHI_GANG_EVENT_HAS_COMPLETE;
            }

            HuaShiGangStrongPoint point = getPoint(huaShiGangUserData.getX(), huaShiGangUserData.getY());
            if (point == null) {
                return GameErrorCode.E_HUA_SHI_GANG_POINT_ERROR;
            }
            synchronized (point) {
                // 判断是否已经打开过贪官宝库
                if (hasOpenTreasure(userBaseInfo, huaShiGangUserData.getX(), huaShiGangUserData.getY())) {
                    return GameErrorCode.E_HUA_SHI_GANG_EVENT_HAS_COMPLETE;
                }
                HuaShiGangTreasure treasure = getTreasure(huaShiGangUserData.getX(), huaShiGangUserData.getY(), treasureId);
                if (treasure == null) {
                    return GameErrorCode.E_HUA_SHI_GANG_NOT_TREASURE;
                }

                if (treasure.getOpenTime() > 0) {
                    return GameErrorCode.E_HUA_SHI_GANG_TREASURE_BEEN_OPEN;
                }

                treasure.setOpenPlayer(userBaseInfo);
                treasure.setOpenTime(System.currentTimeMillis());
                builder = HuaShiGangProto.OpenTreasureFromCross.newBuilder();
                builder.setReward(treasure.getReward());
                builder.setGood(treasure.isGoodReward());

                if (treasure.isGoodReward()) {
                    notifySystemMsg(serverId, playerId, eHuaShiGangMessageType.TREASURE_OPEN.getValue() + GameConfig.TALK_SEPARATOR + treasure.getReward());
                }
            }
        }
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(GameProtocol.S_HUA_SHI_GANG_OPEN_TREASURE_FROM_CROSS, builder));
//        notifyInTreasurePlayersOpen(huaShiGangUserData.getX(), huaShiGangUserData.getY());
        return 0;
    }

    public HuaShiGangProto.OpenTreasureFromCross.Builder randomOpenTreasure(long serverId, long playerId, UserBaseInfo userBaseInfo) {
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        HuaShiGangProto.OpenTreasureFromCross.Builder builder = null;
        synchronized (huaShiGangUserData) {
            if (huaShiGangUserData.isFinish()) {
                return null;
            }

            HuaShiGangStrongPoint point = getPoint(huaShiGangUserData.getX(), huaShiGangUserData.getY());
            if (point == null) {
                return null;
            }
            synchronized (point) {
                // 判断是否已经打开过贪官宝库
                if (hasOpenTreasure(userBaseInfo, huaShiGangUserData.getX(), huaShiGangUserData.getY())) {
                    return null;
                }
                HuaShiGangTreasure treasure = getRandomTreasure(huaShiGangUserData.getX(), huaShiGangUserData.getY());
                if (treasure == null) {
                    return null;
                }

                if (treasure.getOpenTime() > 0) {
                    return null;
                }

                treasure.setOpenPlayer(userBaseInfo);
                treasure.setOpenTime(System.currentTimeMillis());
                builder = HuaShiGangProto.OpenTreasureFromCross.newBuilder();
                builder.setReward(treasure.getReward());
                builder.setGood(treasure.isGoodReward());

                if (treasure.isGoodReward()) {
                    notifySystemMsg(serverId, playerId, eHuaShiGangMessageType.TREASURE_OPEN.getValue() + GameConfig.TALK_SEPARATOR + treasure.getReward());
                }
            }
        }

        return builder;
    }

    /**
     * 通知在宝库中的所有人
     * @param x
     * @param y
     */
//    public void notifyInTreasurePlayersOpen(int x, int y) {
//        try {
//            List<HuaShiGangTreasure> treasureList = huaShiGangTreasureMap.get(HuaShiGangMgr.getKey(x, y));
//            if (treasureList != null && treasureList.size() > 0) {
//                List<Pair<Long, Long>> listPair =  getTreasureInPlayerList(x, y);
//                for (Pair<Long, Long> pair : listPair) {
//                    HuaShiGangProto.GetTreasureListMsgRespMsg.Builder builder = HuaShiGangPb.getHuaShiGangTreasureListPb(treasureList);
//                    MessageHelper.sendChannelPacket(pair.getKey(), pair.getValue(), YanQuMessageUtils.buildMessage(ClientProtocol.U_HUA_SHI_GANG_NOTIFY_TREASURE_LIST, builder));
//                }
//            }
//        } catch (Exception ex) {
//            HuaShiGangMgr.getLogger().error(ex);
//        }
//    }

    /**
     * 判断是否已经打开过贪官宝库
     *
     * @param userBaseInfo
     * @param x
     * @param y
     * @return
     */
    public boolean hasOpenTreasure(UserBaseInfo userBaseInfo, int x, int y) {
        String key = HuaShiGangMgr.getKey(x, y);
        List<HuaShiGangTreasure> treasureList = huaShiGangTreasureMap.get(key);
        if (treasureList == null) {
            return false;
        }

        for (HuaShiGangTreasure treasure : treasureList) {
            if (treasure.getOpenTime() > 0 && treasure.getOpenPlayer().getServerId() == userBaseInfo.getServerId() &&
                    treasure.getOpenPlayer().getUserAliasId() == userBaseInfo.getUserAliasId()) {
                return true;
            }
        }
        return false;
    }


    /**
     * 攻击怪物
     *
     * @param serverId
     * @param playerId
     * @param patronsId
     * @param ability
     * @param userBaseInfo
     * @param costNum
     * @return
     */
    public int attackMonster(long serverId, long playerId, int patronsId, long ability, UserBaseInfo userBaseInfo, int costNum, int talentAddition, int occupationAddition, int bossTalentAddition) {
        long logDamage = 0L;
        BigDecimal calAbility = BigDecimal.valueOf(ability);
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        synchronized (huaShiGangUserData) {
            if (huaShiGangUserData.isFinish()) {
                return GameErrorCode.E_HUA_SHI_GANG_EVENT_HAS_COMPLETE;
            }
            HuaShiGangStrongPoint point = getPoint(huaShiGangUserData.getX(), huaShiGangUserData.getY());
            if (point == null) {
                return GameErrorCode.E_HUA_SHI_GANG_POINT_ERROR;
            }

            synchronized (point) {
                HuaShiGangMode mode = getModeByY(huaShiGangUserData.getY());
                if (mode == null) {
                    return GameErrorCode.E_HUA_SHI_GANG_MODE_ERROR;
                }

                HuaShiGangMonsterData huaShiGangMonsterData = getHuaShiGangMonsterData(huaShiGangUserData.getX(), huaShiGangUserData.getY(), huaShiGangUserData.getMonsterId());
                if (huaShiGangMonsterData == null) {
                    return GameErrorCode.E_HUA_SHI_GANG_MONSTER_NOT_EXIST;
                }

                if (huaShiGangMonsterData.getNowBlood() <= 0) {
                    return GameErrorCode.E_HUA_SHI_GANG_MONSTER_DEAD;
                }

                HuaShiGangActivityEventConfig config = huaShiGangActivityEventConfigMap.get(point.getEventId());
                if (config == null) {
                    return GameErrorCode.E_HUA_SHI_GANG_EVENT_ERROR;
                }

                huaShiGangUserData.initPatrons(patronsId);
                HuaShiGangPatrons patrons = huaShiGangUserData.getPatronsMap().get(patronsId);

                if (mode.getModeType() == eHuaShiGangModeType.C || mode.getModeType() == eHuaShiGangModeType.D) {
                    int y = huaShiGangUserData.getY();
                    int batTimes = patrons.getBatMap().getOrDefault(y, 0);
                    // BOSS怪物逻辑
                    if (batTimes >= newConfig.getBossDispatchCost().size()) {
                        return GameErrorCode.E_HUA_SHI_GANG_ATTACK_TIMES_FULL;
                    }

                    int cost = newConfig.getBossDispatchCost().get(batTimes);
                    if (cost != costNum) {
                        return GameErrorCode.E_HUA_SHI_GANG_COST_ERROR;
                    }

                    patrons.getBatMap().put(y, batTimes + 1);
                    calAbility = calAbility.multiply(BigDecimal.valueOf((occupationAddition < 1000 ? 1000 : occupationAddition) + patrons.getAddition() + bossTalentAddition)).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_UP);  // 1+职业加成+buff
                } else {
                    // 普通怪物逻辑
                    if (patrons.getNat() >= newConfig.getNormalDispatchCost().size()) {
                        return GameErrorCode.E_HUA_SHI_GANG_ATTACK_TIMES_FULL;
                    }

                    int cost = newConfig.getNormalDispatchCost().get(patrons.getNat());
                    if (cost != costNum) {
                        return GameErrorCode.E_HUA_SHI_GANG_COST_ERROR;
                    }

                    patrons.setNat(patrons.getNat() + 1);
                    calAbility = calAbility.multiply(BigDecimal.valueOf((occupationAddition < 1000 ? 1000 : occupationAddition) + patrons.getAddition() + talentAddition)).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_UP);  // 1+职业加成+buff
                }
                ability = calAbility.longValue();

                ability = ability <= 0 ? 1 : ability; //能力值最小为1

                boolean isKill = false;
                long killScore = 0L;
                long damage = huaShiGangMonsterData.getNowBlood() >= ability ? ability : huaShiGangMonsterData.getNowBlood();
                logDamage = damage; // 记一下伤害值
                huaShiGangMonsterData.setNowBlood(huaShiGangMonsterData.getNowBlood() - damage);
                if (huaShiGangMonsterData.getNowBlood() <= 0) {

                    // 【多来几个try，很怂】

                    try {
                        // 击杀
                        isKill = true;
                        huaShiGangMonsterData.setKillPlayer(userBaseInfo);
                        huaShiGangMonsterData.setKillUserId(huaShiGangUserData.getUserId());
                        killScore = calcKillScore(huaShiGangUserData.getX(), huaShiGangUserData.getY(), huaShiGangMonsterData.getMonsterId());
                        huaShiGangUserData.setAllScore(huaShiGangUserData.getAllScore() + killScore);
                        if (mode.getModeType() == eHuaShiGangModeType.C || mode.getModeType() == eHuaShiGangModeType.D) {
                            //击杀蔡京送财
                            ActivityDisperseGoldProto.ActivityDisperseGoldReqMsg.Builder builder = ActivityDisperseGoldProto.ActivityDisperseGoldReqMsg.newBuilder();
                            builder.setActivityId(activityInfo.getActivityId());
                            // 花石纲送财manifesto存boss的eventId
                            int eventId = mode.getPoints()[0][0].getEventId();
                            builder.setManifesto(String.valueOf(eventId));
                            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(GameProtocol.S_ACTIVITY_DISPERSE_GOLD_REQ, builder));
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    try {
                        // 击杀中间boss，生成后续路径
                        if (mode.getModeType() == eHuaShiGangModeType.D) {
                            createNextStageUnit(huaShiGangUserData.getY());
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    // 击杀最后boss，才要设置击杀者
                    if (mode.getModeType() == eHuaShiGangModeType.C) {
                        killBossUserBaseInfo = userBaseInfo;
                    }
                }

                BigDecimal damagePercent = BigDecimal.valueOf(damage).divide(BigDecimal.valueOf(huaShiGangMonsterData.getAllBlood()), 50, BigDecimal.ROUND_UP);
                damagePercent = damagePercent.compareTo(BigDecimal.ONE) >= 0 ? BigDecimal.ONE : damagePercent;
                long addScore = calcDamageScore(huaShiGangMonsterData, damage);

//                HuaShiGangMgr.getLogger().error("damage-- {} {} {} {} {} {} {}", serverId, playerId, patronsId, damagePercent.toString(), damage, addScore, huaShiGangMonsterData.getAllBlood());

                addAttackRecord(huaShiGangUserData.getX(), huaShiGangUserData.getY(), huaShiGangMonsterData.getMonsterId(), playerId, serverId, userBaseInfo, damage);

                // 击杀精英怪：添加排行奖励、同步红点
                if (isKill && mode.getModeType() == eHuaShiGangModeType.B) {
                    addEliteRewardList(point.getY());

                    CrossActivityRankListModel model = getMonsterRankListModel(0, point.getY(), 1);
                    List<CrossUserRank> rankList = new ArrayList<>(model.getRankList());
                    for (int i = 0; i < newConfig.getEliteKillRankScore().size() && i < rankList.size(); i++) {
                        CrossUserRank rank = rankList.get(i);
                        if (rank.getValue().compareTo(BigInteger.ZERO) > 0) {
                            syncEliteRewardRedDot(rank.getUserBaseInfo().getServerId(), rank.getUserId());
                        }
                    }
                }

                huaShiGangUserData.setAllScore(huaShiGangUserData.getAllScore() + addScore);
                huaShiGangUserData.setScoreUpdateTime(System.currentTimeMillis());

                CrossUserRank rank = new CrossUserRank();
                rank.setUserBaseInfo(userBaseInfo);
                rank.setUserId(playerId);
                rank.setLastUpdateTime(huaShiGangUserData.getScoreUpdateTime());
                rank.setValue(BigInteger.valueOf(huaShiGangUserData.getAllScore()));
                crossRankListModel.rankChange(rank);

                HuaShiGangProto.AttackMonsterFromCross.Builder builder = HuaShiGangProto.AttackMonsterFromCross.newBuilder();
                builder.setRet(0);
                builder.setIsKill(isKill);
                builder.setCostNum(costNum);
                builder.setEventId(point.getEventId());
                builder.setDamage(damage);
                builder.setAddScore(addScore + killScore);
                builder.setNewBlood(huaShiGangMonsterData.getNowBlood());
                builder.setPlayerInfo(PlayerBasePb.parsePlayerBaseTempMsg(huaShiGangMonsterData.getKillPlayer()));
                builder.setActivityId(activityInfo.getActivityId());
                builder.setTalentId(patronsId);
                builder.setAllScore(huaShiGangUserData.getAllScore());
                builder.setMonsterId(huaShiGangMonsterData.getMonsterId());
                MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(GameProtocol.S_HUA_SHI_GANG_ATTACK_MONSTER_FROM_CROSS, builder));

                huaShiGangUserData.setUpdateOption();

                // 加入场景
                UserScene userScene = new UserScene(
                        activityInfo.getActivityId(),
                        eSceneType.HuaShiGangMonster.getValue(),
                        huaShiGangMonsterData.getPointKey() + "|" + huaShiGangMonsterData.getMonsterId(),
                        playerId,
                        new ScenePlayerInfo(userBaseInfo.getServerId(), playerId, userBaseInfo.getNickName(), userBaseInfo.getDecoration()),
                        System.currentTimeMillis()
                );
                CrossSceneMgr.addAction(activityInfo.getActivityId(), SceneProto.SceneActionMsg.newBuilder()
                        .setPlayerSceneInfo(ScenePb.parsePlayerSceneMsg(userScene.getPlayerSceneInfo()))
                        .setSceneType(eSceneType.HuaShiGangMonster.getValue())
                        .setSceneId(userScene.getSceneId())
                        .setActionType(eSceneActionType.AttackMonster.getValue())
                        .setCurHp(huaShiGangMonsterData.getNowBlood())
                        .setDamage(damage)
                        .setKill(isKill)
                        .build());

            }

        }
        changeLastHuaShiGangData(huaShiGangUserData);

        synchronized (this) {
            huaShiGangData.setTotalDamage(huaShiGangData.getTotalDamage() + logDamage);
        }

        return 0;
    }

    /**
     * 获取伤害榜单
     *
     * @param serverId
     * @param playerId
     * @return
     */
    public int getMonsterDamageList(long serverId, long playerId) {
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        synchronized (huaShiGangUserData) {
            HuaShiGangStrongPoint point = getPoint(huaShiGangUserData.getX(), huaShiGangUserData.getY());
            if (point == null) {
                return GameErrorCode.E_HUA_SHI_GANG_POINT_ERROR;
            }
            if (huaShiGangUserData.getMonsterId() <= 0) {
                return GameErrorCode.E_HUA_SHI_GANG_EVENT_ERROR;
            }
            CrossActivityRankListModel model = getMonsterRankListModel(point.getX(), point.getY(), huaShiGangUserData.getMonsterId());
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(ClientProtocol.U_HUA_SHI_GANG_GET_ATTACK_RECORD, model.getRankListMsg()));
        }

        return 0;
    }

    /**
     * 精英怪伤害奖励排行
     */
    public int getEliteMonsterDamageRank(long serverId, long playerId, int y) {
        HuaShiGangMode mode = getModeByY(y);
        HuaShiGangStrongPoint point = getPoint(0, y);
        HuaShiGangMonsterData monsterData = getHuaShiGangMonsterData(point.getX(), point.getY(), 1);
        if (mode == null || point == null || monsterData == null || mode.getModeType() != eHuaShiGangModeType.B) {
            return GameErrorCode.E_HUA_SHI_GANG_POINT_ERROR;
        }
        if (monsterData.getMonsterId() <= 0) {
            return GameErrorCode.E_HUA_SHI_GANG_EVENT_ERROR;
        }

        CrossActivityRankListModel model = getMonsterRankListModel(point.getX(), point.getY(), 1);

        List<CrossUserRank> rankList = new ArrayList<>(model.getRankList()).stream()
                .limit(newConfig.getEliteKillRankScore().size())
                .filter(item -> item.getValue().compareTo(BigInteger.ZERO) > 0)
                .collect(Collectors.toList());
        boolean canReward = false;
        if (eliteRewardMap.containsKey(y)) {
            List<HuaShiGangEliteReward> eliteRewardList = new ArrayList<>(eliteRewardMap.get(y));
            canReward = eliteRewardList.stream().anyMatch(item ->
                    item.getUserId() == playerId && item.getServerId() == serverId && !item.isGetReward());

            // 填充下积分（击杀完有存储奖励，从那边拿）
            Map<Long, Long> userScoreMap = new ConcurrentHashMap<>();
            for (HuaShiGangEliteReward eliteReward : eliteRewardList) {
                long scoreCount = PropertyHelper.parseStringToProperty(eliteReward.getReward()).getCountByGoodsId(newConfig.getScoreItemId()).longValue();
                userScoreMap.put(eliteReward.getUserId(), scoreCount);
            }
            for (CrossUserRank rank : rankList) {
                rank.setParam(String.valueOf(userScoreMap.getOrDefault(rank.getUserId(), 0L)));
            }
        } else {
            // 填充下积分（根据血量计算）
            long totalScore = calcTotalScore(monsterData);
            List<Integer> scoreConfig = newConfig.getEliteKillRankScore();
            for (int i = 0; i < rankList.size(); i++) {
                CrossUserRank rank = rankList.get(i);
                int ratio = scoreConfig.size() > i ? scoreConfig.get(i) : 0;
                BigInteger count = new BigDecimal(totalScore).multiply(new BigDecimal(ratio)).divide(new BigDecimal(1000), BigDecimal.ROUND_UP).toBigInteger();
                rank.setParam(count.toString());
            }
        }

        HuaShiGangProto.GetEliteRankListRespMsg.Builder builder = HuaShiGangProto.GetEliteRankListRespMsg.newBuilder();
        builder.setRet(0);
        builder.setCanReward(canReward);
        builder.setRankList(CrossRankPb.parseRankListMsg(rankList));
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(ClientProtocol.U_HUA_SHI_GANG_ELITE_RANK, builder));

        return 0;
    }

    /**
     * 获取攻击过的精英怪列表
     */
    public int getAttackedEliteMonsterList(long serverId, long playerId) {
        List<HuaShiGangProto.HuaShiGangEliteMsg> eliteMsgList = new ArrayList<>();
        // 添加已击杀的精英怪
        for (Map.Entry<Integer, List<HuaShiGangEliteReward>> entry : eliteRewardMap.entrySet()) {
            HuaShiGangStrongPoint point = getPoint(0, entry.getKey());
            HuaShiGangProto.HuaShiGangEliteMsg.Builder eliteMsg = HuaShiGangProto.HuaShiGangEliteMsg.newBuilder();
            eliteMsg.setY(entry.getKey());
            eliteMsg.setIsKill(true);
            eliteMsg.setEventId(point.getEventId());
            eliteMsgList.add(eliteMsg.build());
        }
        // 排序
        eliteMsgList.sort(Comparator.comparing(HuaShiGangProto.HuaShiGangEliteMsg::getY));
        // 如果最前方是精英怪 且 未击杀，也加进来
        int lastX = lastHuaShiGangData.getX();
        int lastY = lastHuaShiGangData.getY();
        HuaShiGangMode lastMode = getModeByY(lastY);
        if (lastMode != null && lastMode.getModeType() == eHuaShiGangModeType.B) {
            HuaShiGangStrongPoint lastPoint = getPoint(lastX, lastY);
            if (lastPoint != null) {
                HuaShiGangActivityEventConfig eventConfig = huaShiGangActivityEventConfigMap.get(lastPoint.getEventId());
                if (eventConfig != null && eventConfig.getEventType() == eHuaShiGangEventType.CREAM_MONSTER.getValue()) {
                    HuaShiGangMonsterData lastMonster = getHuaShiGangMonsterData(0, lastY, 1);
                    if (lastMonster != null && lastMonster.getNowBlood() > 0 && lastMonster.getNowBlood() < lastMonster.getAllBlood()) {
                        HuaShiGangProto.HuaShiGangEliteMsg.Builder builder = HuaShiGangProto.HuaShiGangEliteMsg.newBuilder();
                        builder.setY(lastY);
                        HuaShiGangStrongPoint point = getPoint(0, lastY);
                        builder.setEventId(point.getEventId());
                        builder.setIsKill(false);
                        eliteMsgList.add(builder.build());
                    }
                }
            }
        }

        HuaShiGangProto.GetHuaShiGangEliteListRespMsg.Builder builder = HuaShiGangProto.GetHuaShiGangEliteListRespMsg.newBuilder();
        builder.setRet(0);
        builder.addAllEliteList(eliteMsgList);
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(ClientProtocol.U_HUA_SHI_GANG_ATTACKED_ELITE_LIST, builder));
        return 0;
    }

    /**
     * 获取精英怪伤害排行奖励
     */
    public int getEliteReward(long serverId, long playerId, int y) {
        // 判断精英怪是否被击杀
        List<HuaShiGangEliteReward> tmpEliteRewardList = eliteRewardMap.get(y);
        if (tmpEliteRewardList == null) {
            return GameErrorCode.E_HUA_SHI_GAG_POINT_MONSTER_IS_ALIVE;
        }
        // 判断排名
        List<HuaShiGangEliteReward> eliteRewardList = new ArrayList<>(tmpEliteRewardList);
        for (HuaShiGangEliteReward eliteReward : eliteRewardList) {
            if (eliteReward.getServerId() == serverId && eliteReward.getUserId() == playerId) {
                HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
                synchronized (huaShiGangUserData) {
                    // 判断是否领奖
                    if (!eliteReward.isGetReward()) {
                        // 发奖
                        BigInteger scoreCount = PropertyHelper.parseStringToProperty(eliteReward.getReward()).getCountByGoodsId(getHuaShiGangScoreId());

                        huaShiGangUserData.setAllScore(huaShiGangUserData.getAllScore() + scoreCount.longValue());
                        huaShiGangUserData.setScoreUpdateTime(System.currentTimeMillis());

                        HuaShiGangProto.GetEliteRewardFromCross.Builder builder = HuaShiGangProto.GetEliteRewardFromCross.newBuilder();
                        builder.setRet(0);
                        builder.setReward(eliteReward.getReward());
                        builder.setAllScore(huaShiGangUserData.getAllScore());
                        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(GameProtocol.S_HUA_SHI_GANG_GET_ELITE_REWARD_FROM_CROSS, builder));

                        eliteReward.setIsGetReward(true);

                        // 同步红点
                        syncEliteRewardRedDot(serverId, playerId);
                        return 0;
                    } else {
                        // 已领奖
                        return GameErrorCode.E_HUA_SHI_GANG_ELITE_REWARD_REPEAT;
                    }
                }
            }
        }
        return GameErrorCode.E_HUA_SHI_GANG_ELITE_REWARD_OUT_LIMIT;
    }

    /**
     * 获取精英怪伤害排行奖励
     */
    public int getEliteRewardOneKey(long serverId, long playerId) {
        int ret = 0;
        HuaShiGangProto.GetEliteRewardFromCross.Builder builder = HuaShiGangProto.GetEliteRewardFromCross.newBuilder();
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        for (List<HuaShiGangEliteReward> tmpEliteRewardList : eliteRewardMap.values()) {
            // 判断精英怪是否被击杀
            if (tmpEliteRewardList == null) {
                ret = GameErrorCode.E_HUA_SHI_GAG_POINT_MONSTER_IS_ALIVE;
                continue;
            }
            // 判断排名
            List<HuaShiGangEliteReward> eliteRewardList = new ArrayList<>(tmpEliteRewardList);
            for (HuaShiGangEliteReward eliteReward : eliteRewardList) {
                if (eliteReward.getServerId() == serverId && eliteReward.getUserId() == playerId) {
                    synchronized (huaShiGangUserData) {
                        // 判断是否领奖
                        if (!eliteReward.isGetReward()) {
                            // 发奖
                            BigInteger scoreCount = PropertyHelper.parseStringToProperty(eliteReward.getReward()).getCountByGoodsId(getHuaShiGangScoreId());

                            huaShiGangUserData.setAllScore(huaShiGangUserData.getAllScore() + scoreCount.longValue());
                            huaShiGangUserData.setScoreUpdateTime(System.currentTimeMillis());

                            builder.addRewards(eliteReward.getReward());
                            builder.addY(eliteReward.getY());
                            builder.addRank(eliteReward.getRank());
                            eliteReward.setIsGetReward(true);
                        } else {
                            // 已领奖
                            ret = GameErrorCode.E_HUA_SHI_GANG_ELITE_REWARD_REPEAT;
                        }
                    }
                }
            }
        }
        if (!builder.getRewardsList().isEmpty()) {
            ret = 0;
        }
        if (ret == 0) {
            builder.setRet(0);
            builder.setAllScore(huaShiGangUserData.getAllScore());
            builder.setOneKey(true);
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(GameProtocol.S_HUA_SHI_GANG_GET_ELITE_REWARD_FROM_CROSS, builder));
            // 同步红点
            syncEliteRewardRedDot(serverId, playerId);
        }
        return ret;
    }

    /**
     * 同步精英怪奖励红点
     */
    public void syncEliteRewardRedDot(long serverId, long playerId) {
        List<Integer> redDotList = getEliteRewardRedDotList(serverId, playerId);
        String redDotStr = StringUtils.listToString(redDotList, "|");
        WorldMessageProto.RedHotNotifyMsg.Builder builder = WorldMessageProto.RedHotNotifyMsg.newBuilder();
        builder.setParam(redDotStr);
        builder.setCount(redDotList.size());
        builder.setType(eRedHotNotifyType.HuaShiGangEliteRankReward.getValue());
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(ClientProtocol.U_RED_HOT_NOTIFY, builder));
    }

    /**
     * 获取精英怪伤害奖励红点
     */
    public List<Integer> getEliteRewardRedDotList(long serverId, long playerId) {
        List<Integer> yList = new ArrayList<>();
        for (List<HuaShiGangEliteReward> tmpEliteRewardList : eliteRewardMap.values()) {
            List<HuaShiGangEliteReward> eliteRewardList = new ArrayList<>(tmpEliteRewardList);
            for (HuaShiGangEliteReward eliteReward : eliteRewardList) {
                if (!eliteReward.isGetReward() && eliteReward.getServerId() == serverId && eliteReward.getUserId() == playerId) {
                    yList.add(eliteReward.getY());
                }
            }
        }
        return yList;
    }

    /**
     * 完成当前据点
     *
     * @param serverId
     * @param playerId
     * @return
     */
    public int completePoint(long serverId, long playerId) {
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        synchronized (huaShiGangUserData) {
            HuaShiGangStrongPoint point = getPoint(huaShiGangUserData.getX(), huaShiGangUserData.getY());
            if (point == null) {
                return GameErrorCode.E_HUA_SHI_GANG_POINT_ERROR;
            }

            HuaShiGangActivityEventConfig config = getHuaShiGangActivityEventConfigMap().get(point.getEventId());
            HuaShiGangMode mode = getModeByY(huaShiGangUserData.getY());

            // 宝箱事件都可以跳过
            if (eHuaShiGangEventType.BOX_EVENT.getValue() != config.getEventType() && huaShiGangUserData.isFinish()) {
                return GameErrorCode.E_HUA_SHI_GANG_EVENT_CAN_NOT_COMPLETE;
            }

            if (eHuaShiGangEventType.isMonsterEvent(config.getEventType())) {
                HuaShiGangMonsterData monster = getHuaShiGangMonsterData(huaShiGangUserData.getX(), huaShiGangUserData.getY(), huaShiGangUserData.getMonsterId());
                if (monster.getNowBlood() > 0) {
                    //怪物未被击败
                    return GameErrorCode.E_HUA_SHI_GAG_POINT_MONSTER_IS_ALIVE;
                }
                huaShiGangUserData.setFinish(true);
                if (mode.getModeType() == eHuaShiGangModeType.D) {
                    Point nextPoint = point.getNextList().get(0);
                    huaShiGangUserData.reset((int) nextPoint.getX(), (int) nextPoint.getY());
                    huaShiGangUserData.setFinish(true);
                }
            } else if (eHuaShiGangEventType.isTradeEvent(config.getEventType())) {
                // 贸易事件
                huaShiGangUserData.setFinish(true);
            } else if (eHuaShiGangEventType.isTreasureEvent(config.getEventType())) {
                // 宝藏事件 玩家选择宝箱 判断是否还有宝藏来决定是否finish
                huaShiGangUserData.setFinish(true);
                checkTreasureOutPlayers(huaShiGangUserData.getServerId(), huaShiGangUserData.getUserId(), huaShiGangUserData.getX(), huaShiGangUserData.getY());

            } else if (eHuaShiGangEventType.BOX_EVENT.getValue() == config.getEventType()) {
                // 宝箱事件
                huaShiGangUserData.setFinish(true);
            } else if (eHuaShiGangEventType.SHOP_EVENT.getValue() == config.getEventType()) {
                // 商店事件
                HuaShiGangProto.HuaShiGangNotifyGameServerShop.Builder builder = HuaShiGangProto.HuaShiGangNotifyGameServerShop.newBuilder();
                builder.setStat(1);
                MessageHelper.sendPacket(huaShiGangUserData.getServerId(), huaShiGangUserData.getUserId(), YanQuMessageUtils.buildMessage(GameProtocol.S_HUA_SHI_GANG_NOTIFY_SHOP_FROM_CROSS, builder));
                huaShiGangUserData.setFinish(true);
            } else if (eHuaShiGangEventType.UNEXPECTED_EVENT.getValue() == config.getEventType()) {
                // 意外事件
                huaShiGangUserData.setFinish(true);
            }
            return 0;
        }
    }

    /**
     * 自动处理下一个坐标的事件
     */
    public HuaShiGangAutoResult autoCompleteNextPointEvent(long serverId, long playerId, UserBaseInfo userBaseInfo,
                                                           List<Integer> patronsList, List<Long> abilityList, List<Integer> additionList) {
        HuaShiGangAutoResult result = new HuaShiGangAutoResult();
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        synchronized (huaShiGangUserData) {
            HuaShiGangStrongPoint point = getPoint(huaShiGangUserData.getX(), huaShiGangUserData.getY());
            if (point == null) {
                result.setRet(GameErrorCode.E_HUA_SHI_GANG_POINT_ERROR);
                return result;
            }
            HuaShiGangActivityEventConfig config = getHuaShiGangActivityEventConfigMap().get(point.getEventId());
            // 宝箱事件可以是已完成状态
            if (huaShiGangUserData.isFinish() && config.getEventType() != eHuaShiGangEventType.BOX_EVENT.getValue()) {
                result.setRet(GameErrorCode.E_HUA_SHI_GANG_EVENT_HAS_COMPLETE);
                return result;
            }
            List<Integer> openSwitchList = huaShiGangUserData.getOpenSwitchList();
            result.setEventType(config.getEventType());
            result.setEventId(config.getEventId());

            // 宝箱事件（移动据点时已经把宝箱加到列表里了，这里直接跳过）
            if (eHuaShiGangEventType.BOX_EVENT.getValue() == config.getEventType() && openSwitchList.contains(eHuaShiGangSwitchType.BOX.getValue())) {
                result.setBoxStatus(huaShiGangUserData.isFinish() ? 1 : 0); // 1已开启
                result.setEventId(huaShiGangUserData.getBoxEventId());
                huaShiGangUserData.setFinish(true);
                return result;
            }
            // 怪物事件（血量不为0无法跳过）
            else if (eHuaShiGangEventType.isMonsterEvent(config.getEventType()) && openSwitchList.contains(eHuaShiGangSwitchType.MONSTER.getValue())) {
                HuaShiGangMonsterData monster = getHuaShiGangMonsterData(huaShiGangUserData.getX(), huaShiGangUserData.getY(), huaShiGangUserData.getMonsterId());
                if (monster.getNowBlood() > 0) {
                    result.setStopReason(1);
                } else if (config.getEventType() == eHuaShiGangEventType.BOSS_MONSTER.getValue()) {
                    result.setStopReason(3);
                } else {
                    huaShiGangUserData.setFinish(true);
                }
                return result;
            }
            // 贸易事件（直接完成，返回本服时再交易）
            else if (eHuaShiGangEventType.isTradeEvent(config.getEventType()) && openSwitchList.contains(eHuaShiGangSwitchType.TRADE.getValue())) {
                result.setReward(config.getRewards());
                result.setConsume(config.getParamList());
                huaShiGangUserData.setFinish(true);
                return result;
            }
            // 宝藏事件（需要判断是否开启过）
            else if (eHuaShiGangEventType.isTreasureEvent(config.getEventType()) && openSwitchList.contains(eHuaShiGangSwitchType.TREASURE.getValue())) {
                String key = HuaShiGangMgr.getKey(huaShiGangUserData.getX(), huaShiGangUserData.getY());
                List<HuaShiGangTreasure> treasureList = huaShiGangTreasureMap.get(key);
                if (treasureList != null) {
                    synchronized (point) {
                        result.setBoxStatus(1); // 1全部被开启过
                        if (!hasOpenTreasure(userBaseInfo, huaShiGangUserData.getX(), huaShiGangUserData.getY())) {
                            for (HuaShiGangTreasure treasure : treasureList) {
                                if (treasure.getOpenTime() == 0) {
                                    result.setReward(treasure.getReward());
                                    result.setBoxStatus(0); // 0正常开启
                                    treasure.setOpenPlayer(userBaseInfo);
                                    treasure.setOpenTime(System.currentTimeMillis());
                                    if (treasure.isGoodReward()) {
                                        notifySystemMsg(serverId, playerId, eHuaShiGangMessageType.TREASURE_OPEN.getValue() + GameConfig.TALK_SEPARATOR + treasure.getReward());
                                    }
                                    break;
                                }
                            }
                        } else {
                            result.setBoxStatus(2); // 2手动开启过了
                        }
                    }
                }
                huaShiGangUserData.setFinish(true);
                return result;
            }
//            // 商店事件
//            else if (eHuaShiGangEventType.SHOP_EVENT.getValue() == config.getEventType()) {
//                HuaShiGangProto.HuaShiGangNotifyGameServerShop.Builder builder = HuaShiGangProto.HuaShiGangNotifyGameServerShop.newBuilder();
//                builder.setStat(1);
//                MessageHelper.sendChannelPacket(huaShiGangUserData.getServerId(), huaShiGangUserData.getUserId(), YanQuMessageUtils.buildMessage(GameProtocol.S_HUA_SHI_GANG_NOTIFY_SHOP_FROM_CROSS, builder));
//                huaShiGangUserData.setFinish(true);
//                return result;
//            }
            // 意外事件
            else if (eHuaShiGangEventType.UNEXPECTED_EVENT.getValue() == config.getEventType() && // 客栈 && ( 增益 && 有开增益开关 || 减益 && 有开减益开关 )
                    (config.getAddition() > 0 && openSwitchList.contains(eHuaShiGangSwitchType.ABILITY_ADD.getValue()) ||
                            config.getAddition() < 0 && openSwitchList.contains(eHuaShiGangSwitchType.ABILITY_DEC.getValue()))) {
                int maxId = 0;
                long maxAbility = 0;
                for (int patronsId : huaShiGangUserData.getRandomPatronsId()) {
                    int index = patronsList.indexOf(patronsId);
                    long ability = abilityList.get(index);
                    int occuAddition = additionList.get(index);
                    int eventAddition = 0;
                    HuaShiGangPatrons huaShiGangPatrons = huaShiGangUserData.getPatronsMap().get(patronsId);
                    if (huaShiGangPatrons != null) {
                        eventAddition = huaShiGangPatrons.getAddition();
                    }
                    // 赚钱 = 门客赚钱 x (1 + 职业 + 事件)
                    long finalAbility = BigDecimal.valueOf(ability)
                            .multiply(BigDecimal.valueOf((occuAddition < 1000 ? 1000 : occuAddition) + eventAddition))
                            .divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_UP).longValue();
                    // 比较
                    if (maxId == 0 ||
                            config.getAddition() > 0 && finalAbility > maxAbility ||
                            config.getAddition() < 0 && finalAbility < maxAbility) {
                        maxId = patronsId;
                        maxAbility = finalAbility;
                    }
                }
                result.setPatronsId(maxId);
                result.setPatronsAdd(config.getAddition());
                huaShiGangUserData.initPatrons(maxId);
                HuaShiGangPatrons huaShiGangPatrons = huaShiGangUserData.getPatronsMap().get(maxId);
                huaShiGangPatrons.setAddition(huaShiGangPatrons.getAddition() + config.getAddition());
                huaShiGangUserData.setUpdateOption();
                huaShiGangUserData.setFinish(true);
                return result;
            } else {
                result.setStopReason(2);
                return result;
            }
        }
    }

    public int getHuaShiGangMonsterData(long serverId, long playerId, UserScene userScene) {
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        synchronized (huaShiGangUserData) {
            HuaShiGangStrongPoint point = getPoint(huaShiGangUserData.getX(), huaShiGangUserData.getY());
            if (point == null) {
                return GameErrorCode.E_HUA_SHI_GANG_POINT_ERROR;
            }

            HuaShiGangMonsterData monsterData = getHuaShiGangMonsterData(point.getX(), point.getY(), huaShiGangUserData.getMonsterId());
            if (monsterData == null) {
                return GameErrorCode.E_HUA_SHI_GANG_EVENT_ERROR;
            }

            // 加入场景
            userScene.setSceneId(monsterData.getPointKey() + "|" + monsterData.getMonsterId());
            CrossSceneMgr.enterScene(userScene, true);
            CrossSceneMgr.addAction(activityInfo.getActivityId(), SceneProto.SceneActionMsg.newBuilder()
                    .setPlayerSceneInfo(ScenePb.parsePlayerSceneMsg(userScene.getPlayerSceneInfo()))
                    .setSceneType(eSceneType.HuaShiGangMonster.getValue())
                    .setSceneId(monsterData.getPointKey() + "|" + monsterData.getMonsterId())
                    .setActionType(eSceneActionType.EnterScene.getValue())
                    .setCurHp(monsterData.getNowBlood())
                    .build());

            HuaShiGangProto.GetHuaShiGangMonsterDataRespMsg.Builder builder = HuaShiGangProto.GetHuaShiGangMonsterDataRespMsg.newBuilder();
            builder.setRet(0);
            builder.setBlood(monsterData.getNowBlood());
            builder.setFullBlood(monsterData.getAllBlood());
            if (builder.getBlood() <= 0) {
                builder.setPlayerInfo(PlayerBasePb.parsePlayerBaseTempMsg(monsterData.getKillPlayer()));
                builder.setKillUserId(monsterData.getKillUserId());
            }
            List<UserScene> sceneUserList = CrossSceneMgr.getSceneUserList(userScene.getActivityId(), userScene.getSceneType(), userScene.getSceneId(), 30);
            for (UserScene scene : sceneUserList) {
                builder.addPlayerList(ScenePb.parsePlayerSceneMsg(scene.getPlayerSceneInfo()));
            }
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(ClientProtocol.U_HUA_SHI_GANG_GET_MONSTER_DATA, builder));
            return 0;
        }
    }

    /**
     * 获取y后3层的数据
     *
     * @param y
     * @return
     */
    public List<HuaShiGangStrongPoint> getUserNextPoints(int y) {
        List<HuaShiGangStrongPoint> huaShiGangStrongPointList = new ArrayList<>();
        int maxY = y + 5;
        y = y - 1;
        for (; y < maxY; y++) {
            for (int x = 0; x < 3; x++) {
                HuaShiGangStrongPoint point = getPoint(x, y);
                if (point != null) {
                    huaShiGangStrongPointList.add(point);
                }
            }
        }
        return huaShiGangStrongPointList;
    }


    public List<HuaShiGangMode> getHuaShiGangModeList() {
        return huaShiGangModeList;
    }

    public void setHuaShiGangModeList(List<HuaShiGangMode> huaShiGangModeList) {
        this.huaShiGangModeList = huaShiGangModeList;
    }

    public Map<Integer, HuaShiGangActivityEventConfig> getHuaShiGangActivityEventConfigMap() {
        return huaShiGangActivityEventConfigMap;
    }

    public void setHuaShiGangActivityEventConfigMap(Map<Integer, HuaShiGangActivityEventConfig> huaShiGangActivityEventConfigMap) {
        this.huaShiGangActivityEventConfigMap = huaShiGangActivityEventConfigMap;
    }

    public Map<String, List<HuaShiGangMonsterData>> getHuaShiGangMonsterDataMap() {
        return huaShiGangMonsterDataMap;
    }

    public void setHuaShiGangMonsterDataMap(Map<String, List<HuaShiGangMonsterData>> huaShiGangMonsterDataMap) {
        this.huaShiGangMonsterDataMap = huaShiGangMonsterDataMap;
    }

    public Map<String, List<HuaShiGangTreasure>> getHuaShiGangTreasureMap() {
        return huaShiGangTreasureMap;
    }

    public void setHuaShiGangTreasureMap(Map<String, List<HuaShiGangTreasure>> huaShiGangTreasureMap) {
        this.huaShiGangTreasureMap = huaShiGangTreasureMap;
    }

    public Map<String, Map<Integer, Map<Long, HuaShiGangAttackRecord>>> getAttackRecordMap() {
        return attackRecordMap;
    }

    public void setAttackRecordMap(Map<String, Map<Integer, Map<Long, HuaShiGangAttackRecord>>> attackRecordMap) {
        this.attackRecordMap = attackRecordMap;
    }

    public Map<Long, HuaShiGangUserData> getUserDataMap() {
        return userDataMap;
    }

    public void setUserDataMap(Map<Long, HuaShiGangUserData> userDataMap) {
        this.userDataMap = userDataMap;
    }

    public Map<Long, Object> getUserLocker() {
        return userLocker;
    }

    public void setUserLocker(Map<Long, Object> userLocker) {
        this.userLocker = userLocker;
    }

    public void save() {
        if (huaShiGangData != null) {
            if (huaShiGangData.isInsertOption()) {
                UserHuaShiGangBusiness.addData(huaShiGangData);
            } else if (huaShiGangData.isUpdateOption()) {
                UserHuaShiGangBusiness.updateData(huaShiGangData);
            }
        }

        for (HuaShiGangUserData huaShiGangUserData : userDataMap.values()) {
            if (huaShiGangUserData.isUpdateOption()) {
                UserHuaShiGangBusiness.updateData(huaShiGangUserData);
            } else if (huaShiGangUserData.isInsertOption()) {
                UserHuaShiGangBusiness.addData(huaShiGangUserData);
            }
        }

        for (List<HuaShiGangMonsterData> list : huaShiGangMonsterDataMap.values()) {
            int size = list.size();
            for (int i = 0; i < size; i++) {
                HuaShiGangMonsterData monsterData = list.get(i);
                if (monsterData.isUpdateOption()) {
                    UserHuaShiGangBusiness.updateData(monsterData);
                } else if (monsterData.isInsertOption()) {
                    UserHuaShiGangBusiness.addData(monsterData);
                }
            }
        }

        for (List<HuaShiGangTreasure> list : huaShiGangTreasureMap.values()) {
            int size = list.size();
            for (int i = 0; i < size; i++) {
                HuaShiGangTreasure treasure = list.get(i);
                if (treasure.isUpdateOption()) {
                    UserHuaShiGangBusiness.updateData(treasure);
                } else if (treasure.isInsertOption()) {
                    UserHuaShiGangBusiness.addData(treasure);
                }

                // userbaseinfo设置为同一个引用避免浪费内存
                // 如果奖励已经被打开
                if (treasure.getOpenTime() > 0) {
                    long sid = treasure.getOpenPlayer().getServerId();
                    long shortUid = treasure.getOpenPlayer().getUserAliasId();
                    String userIdStr = "" + sid + String.valueOf(shortUid).substring(4);
                    long userId = Long.valueOf(userIdStr);

                    HuaShiGangUserData huaShiGangUserData = userDataMap.get(userId);
                    if (huaShiGangUserData != null && userId == huaShiGangUserData.getUserId()) {
                        treasure.setOpenPlayerNotUpdate(huaShiGangUserData.getUserBaseInfo());
                    }
                }
            }
        }

        for (Map<Integer, Map<Long, HuaShiGangAttackRecord>> ilmap : attackRecordMap.values()) {
            for (Map<Long, HuaShiGangAttackRecord> lmap : ilmap.values()) {
                for (HuaShiGangAttackRecord record : lmap.values()) {
                    if (record.isUpdateOption()) {
                        UserHuaShiGangBusiness.updateData(record);
                    } else if (record.isInsertOption()) {
                        UserHuaShiGangBusiness.addData(record);
                    }

                    // userbaseinfo设置为同一个引用避免浪费内存
                    HuaShiGangUserData huaShiGangUserData = userDataMap.get(record.getUserId());
                    if (huaShiGangUserData != null && record.getUserId() == huaShiGangUserData.getUserId()) {
                        record.setUserBaseInfoNotUpdate(huaShiGangUserData.getUserBaseInfo());
                    }
                }
            }
        }

        for (List<HuaShiGangEliteReward> eliteRewardList : eliteRewardMap.values()) {
            int size = eliteRewardList.size();
            for (int i = 0; i < size; i++) {
                HuaShiGangEliteReward eliteReward = eliteRewardList.get(i);
                if (eliteReward.isInsertOption()) {
                    UserHuaShiGangBusiness.addData(eliteReward);
                } else if (eliteReward.isUpdateOption()) {
                    UserHuaShiGangBusiness.updateData(eliteReward);
                }
            }
        }


        // 热更代码
        try {
            long nowTime = System.currentTimeMillis() / 1000;
            if(nowTime >= activityInfo.getEndTime() + 5 * 60){
                if (!attackRecordMap.isEmpty() || !monsterRankListModelMap.isEmpty()) {
                    HuaShiGangMgr.huaShiGangLogger
                            .info("花石纲"+activityInfo.getActivityId()+"清数据{},{}",attackRecordMap.size(),monsterRankListModelMap.size());
                }
                attackRecordMap.clear();
                huaShiGangTreasureMap.clear();

                // 仅剩下精英怪榜单 不需要移除
                //monsterRankListModelMap.clear();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 设置区服前一天的总能力值
     *
     * @param serverId
     * @param ability
     */
    public synchronized void setAbility(long serverId, long ability) {
        if (!huaShiGangData.getAbilityMap().containsKey(serverId)) {
            huaShiGangData.getAbilityMap().put(serverId, ability);
            huaShiGangData.setUpdateOption();
        } else {
            HuaShiGangMgr.huaShiGangLogger.info("reset server ability, {} {} {}", activityInfo.getActivityId(), serverId, ability);
        }
    }

    /**
     * 获取所有层数据
     * @param serverId
     * @param playerId
     */
    public void getAllPoints(long serverId, long playerId) {
        List<HuaShiGangStrongPoint> huaShiGangStrongPointList = new ArrayList<>();
        for (HuaShiGangMode huaShiGangMode : getHuaShiGangModeList()) {
            for (HuaShiGangStrongPoint[] ps : huaShiGangMode.getPoints()) {
                for (HuaShiGangStrongPoint p : ps) {
                    if (p != null) {
                        huaShiGangStrongPointList.add(p);
                    }
                }
            }
        }
        HuaShiGangProto.HuaShiGangAllData.Builder builder = HuaShiGangProto.HuaShiGangAllData.newBuilder();
        builder.addAllAllPoints(HuaShiGangPb.getHuaShiGangStrongPointPbList(huaShiGangStrongPointList));
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(ClientProtocol.U_HUA_SHI_GANG_GET_ALL, builder));
    }

    /**
     * 根据活动子类型获取活动积分id
     * @param
     * @return
     */
    public int getHuaShiGangScoreId() {
        return newConfig.getScoreItemId();
    }

    /**
     * 根据活动子类型获取活动出战令id
     * @param
     * @return
     */
    public int getHuaShiGangGoldKeyId() {
        return newConfig.getGoldKeyId();
    }

    /**
     * 是否满足神行千里
     */
    public boolean canShenXing(HuaShiGangUserData huaShiGangUserData) {
        boolean shenxing;
        if(huaShiGangUserData.getY() < 0){
            return false;
        }
        HuaShiGangMode nowMode = getModeByY(huaShiGangUserData.getY());
        //处于精英怪据点
        if(nowMode != null && nowMode.getModeType() == eHuaShiGangModeType.B && huaShiGangUserData.getMonsterId() > 0){
            shenxing = false;
        }else {
            HuaShiGangMonsterData tempMonster = getClosestJingYingOrBossMonsterData(huaShiGangUserData);
            if(tempMonster == null){
                shenxing = false;
            }else {
                List<Integer> list = StringUtils.stringToIntegerList(tempMonster.getPointKey(), "-");
                int y = list.get(1);
                if((y - huaShiGangUserData.getY()) * 10 <= GameConfig.HUASHIGUANG_SHENXING_OPEN_DISTANCE){
                    shenxing = false;
                }else {
                    shenxing = true;
                }
            }
        }
        return  shenxing;
    }

    /**
     * 获取最靠近的未被击杀的精英怪(或者BOSS)
     */
    public HuaShiGangMonsterData getClosestJingYingOrBossMonsterData(HuaShiGangUserData huaShiGangUserData) {
        HuaShiGangMonsterData tempMonster = getClosestJingYingMonsterData(huaShiGangUserData, true);
        //boss
        if(tempMonster == null){
            HuaShiGangMode mode = huaShiGangModeList.get(huaShiGangModeList.size() - 1);
            if (mode.getModeType() == eHuaShiGangModeType.C) {
                tempMonster = getHuaShiGangRandomMonsterData(mode.getPoints()[0][0].getX(), mode.getPoints()[0][0].getY());
            }
        }
        return tempMonster;
    }

    /**
     * 获取最靠近的未被击杀的精英怪
     */
    public HuaShiGangMonsterData getClosestJingYingMonsterData(HuaShiGangUserData huaShiGangUserData, boolean live) {
        int tempY = Integer.MAX_VALUE;
        HuaShiGangMonsterData tempMonster = null;
        for (Map.Entry<String, List<HuaShiGangMonsterData>> monsterListEntry : huaShiGangMonsterDataMap.entrySet()) {
            List<Integer> list = StringUtils.stringToIntegerList(monsterListEntry.getKey(), "-");
            int y = list.get(1);
            if(y < huaShiGangUserData.getY()){
                continue;
            }
            HuaShiGangMode mode = getModeByY(y);
            if(mode == null || mode.getModeType() != eHuaShiGangModeType.B){
                continue;
            }
            List<HuaShiGangMonsterData> monsterDataList = monsterListEntry.getValue();
            int size = monsterDataList.size();
            for(int i = 0; i < size; i++){
                HuaShiGangMonsterData monsterData = monsterDataList.get(i);
                if(live && monsterData.getNowBlood() <= 0){
                    continue;
                }
                if(y < tempY){
                    tempMonster = monsterData;
                    tempY = y;
                }
            }
        }
        return tempMonster;
    }

    /**
     * 获取神行千里下一个Y
     *
     * @return -1表示没救了
     */
    public int getNextShenXingY(HuaShiGangUserData huaShiGangUserData) {
        int curY = huaShiGangUserData.getY();
        HuaShiGangMode curMode = getModeByY(curY);

        // 处于起始点、精英怪、BOSS上不能神行
        if (curMode == null
                || curMode.getModeType() == eHuaShiGangModeType.B
                || curMode.getModeType() == eHuaShiGangModeType.C
                || curMode.getModeType() == eHuaShiGangModeType.D) {
            if (huaShiGangUserData.getMonsterId() > 0) {
                return -1;
            }
        }

        int nextAliveY = huaShiGangModeList.size() * 3 - 3; // 先等于最后一个模块的怪物Y，如果全部阵亡，那就以这个位置作为最后位置
        int nextDeadY = -1;

        for (Map.Entry<String, List<HuaShiGangMonsterData>> monsterListEntry : huaShiGangMonsterDataMap.entrySet()) {
            int monsterY = StringUtils.stringToIntegerList(monsterListEntry.getKey(), "-").get(1);

            // 跳过后面的
            if (monsterY <= curY) {
                continue;
            }

            // 跳过非精英、boss模块
            HuaShiGangMode mode = getModeByY(monsterY);
            if (mode == null) {
                continue;
            }
            if (mode.getModeType() != eHuaShiGangModeType.B &&
                    mode.getModeType() != eHuaShiGangModeType.C &&
                    mode.getModeType() != eHuaShiGangModeType.D) {
                continue;
            }

            // 判断怪物是否挂了
            boolean dead = true;
            for (HuaShiGangMonsterData monsterData : monsterListEntry.getValue()) {
                if (monsterData.getNowBlood() > 0) {
                    dead = false;
                    break;
                }
            }

            // 设置最近怪物
            if (dead) {
                if (nextDeadY == -1 || nextDeadY > monsterY) {
                    nextDeadY = monsterY;
                }
            } else {
                if (nextAliveY > monsterY) {
                    nextAliveY = monsterY;
                }
            }
        }

        // 未达到神行距离，无法神行
        if ((nextAliveY - curY) * 10 < GameConfig.HUASHIGUANG_SHENXING_OPEN_DISTANCE) {
            return -1;
        }

        // 跨过中间boss，无法神行
        for (Integer bossY : huaShiGangData.getBossYList()) {
            if (curY <= bossY && nextDeadY > bossY) {
                return -1;
            }
        }

        return nextDeadY;
    }

    /**
     * 获取下一藏宝库的Y
     *
     * @param huaShiGangUserData
     * @return
     */
    public int getNextTreasureY(HuaShiGangUserData huaShiGangUserData) {
        int curY = huaShiGangUserData.getY();
        HuaShiGangMode curMode = getModeByY(curY);

        // 处于起始点、精英怪、BOSS上不能神行
        if (curMode == null
                || curMode.getModeType() == eHuaShiGangModeType.B
                || curMode.getModeType() == eHuaShiGangModeType.C
                || curMode.getModeType() == eHuaShiGangModeType.D) {
            if (huaShiGangUserData.getMonsterId() > 0) {
                return -1;
            }
        }

        int nextAliveY = huaShiGangModeList.size() * 3 - 3; // 先等于最后一个模块的怪物Y，如果全部阵亡，那就以这个位置作为最后位置

        // 未达到神行距离，无法神行
        if ((nextAliveY - curY) * 10 < GameConfig.HUASHIGUANG_SHENXING_OPEN_DISTANCE) {
            return -1;
        }

        //最远能去的Y
        int farthestY = nextAliveY - GameConfig.HUASHIGUANG_SHENXING_OPEN_DISTANCE / 10;

        int nextTreasureY = -1;

        for (int findY = curY + 1; findY <= farthestY; findY++) {
            // 未达到神行距离，无法神行
            if ((nextAliveY - findY) * 10 < GameConfig.HUASHIGUANG_SHENXING_OPEN_DISTANCE) {
                break;
            }

            // 跳过非精英、boss模块
            HuaShiGangMode mode = getModeByY(findY);
            if (mode == null) {
                continue;
            }
            if (mode.getModeType() != eHuaShiGangModeType.B &&
                    mode.getModeType() != eHuaShiGangModeType.C &&
                    mode.getModeType() != eHuaShiGangModeType.D) {
                continue;
            }

            HuaShiGangMonsterData huaShiGangRandomMonsterData = getHuaShiGangRandomMonsterData(0, findY);
            if (huaShiGangRandomMonsterData != null) {
                if (huaShiGangRandomMonsterData.getNowBlood() > 0) {
                    nextAliveY = findY;
                    break;
                }
            }

            String key = HuaShiGangMgr.getKey(0, findY);
            List<HuaShiGangTreasure> treasureList = huaShiGangTreasureMap.get(key);
            if (treasureList == null) {
                continue;
            }

            nextTreasureY = findY;

            //找到宝库后,再往后找200里判断是否有活的精英怪
            int nextY = findY + GameConfig.HUASHIGUANG_SHENXING_OPEN_DISTANCE / 10;
            for (int i = findY + 1; i <= nextY; i++) {
                // 跳过非精英、boss模块
                HuaShiGangMode chcekMode = getModeByY(i);
                if (chcekMode == null) {
                    break;
                }
                if (chcekMode.getModeType() != eHuaShiGangModeType.B &&
                        chcekMode.getModeType() != eHuaShiGangModeType.C &&
                        chcekMode.getModeType() != eHuaShiGangModeType.D) {
                    continue;
                }
                HuaShiGangMonsterData huaShiGangRandomMonsterData1 = getHuaShiGangRandomMonsterData(0, i);
                if (huaShiGangRandomMonsterData1 != null) {
                    if (huaShiGangRandomMonsterData1.getNowBlood() > 0) {
                        nextAliveY = i;
                        break;
                    }
                }
            }

            break;
        }

        // 未达到神行距离，无法神行
        if ((nextAliveY - nextTreasureY) * 10 < GameConfig.HUASHIGUANG_SHENXING_OPEN_DISTANCE) {
            return -1;
        }

        return nextTreasureY;
    }

    /**
     * 神行千里
     */
    public int shenXing(long serverId, long playerId, UserBaseInfo userBaseInfo) {
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        huaShiGangUserData.setUserBaseInfo(userBaseInfo);

        synchronized (huaShiGangUserData) {
            HuaShiGangMode nowMode = getModeByY(huaShiGangUserData.getY());
            //处于精英怪据点
            if (nowMode != null && nowMode.getModeType() == eHuaShiGangModeType.B && huaShiGangUserData.getMonsterId() > 0) {
                return 0;
            }
            //下一个神行Y
            int shenXingY = getNextShenXingY(huaShiGangUserData);
            if (shenXingY != -1) {
                // 这两个写死
                int shenXingX = 0;
                int monsterId = 1;

                HuaShiGangMonsterData monsterData = getHuaShiGangMonsterData(shenXingX, shenXingY, monsterId);

                huaShiGangUserData.reset(shenXingX, shenXingY);

                huaShiGangUserData.setFinish(false);
                huaShiGangUserData.setMonsterId(monsterData.getMonsterId());
                if (monsterData.getNowBlood() > 0) {
                    addAttackRecord(huaShiGangUserData.getX(), huaShiGangUserData.getY(), monsterData.getMonsterId(), huaShiGangUserData.getUserId(), huaShiGangUserData.getServerId(), huaShiGangUserData.getUserBaseInfo(), 0);
                }
            }
        }
        return 0;
    }

    public int shenXingType1(long serverId, long playerId, UserBaseInfo userBaseInfo) {
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        huaShiGangUserData.setUserBaseInfo(userBaseInfo);

        HuaShiGangProto.ShenXingQianLiCrossRespMsg.Builder backMsg = HuaShiGangProto.ShenXingQianLiCrossRespMsg.newBuilder();
        backMsg.setRet(0);

        synchronized (huaShiGangUserData) {
            HuaShiGangStrongPoint point = getPoint(huaShiGangUserData.getX(), huaShiGangUserData.getY());
            if (point != null) {
                HuaShiGangActivityEventConfig eventConfig = getHuaShiGangActivityEventConfigMap().get(point.getEventId());
                if (eventConfig != null && eventConfig.getEventType() == eHuaShiGangEventType.TREASURE_EVENT.getValue()) {
                    if (!huaShiGangUserData.isFinish()) {//宝库一定要完成
                        return GameErrorCode.E_HUA_SHI_GANG_EVENT_NOT_COMPLETE;
                    }
                }
            }


            boolean isStop = false;
            for (int i = 0; i < 10000; i++) {//假装是while
                //找到下一个宝库的位置,有自动开就开,然后继续找,没自动开就停那里
                int nextTreasureY = getNextTreasureY(huaShiGangUserData);
                if (nextTreasureY == -1) {
                    break;
                }

                HuaShiGangStrongPoint treasurePoint = getPoint(0, nextTreasureY);
                HuaShiGangActivityEventConfig eventConfig = getHuaShiGangActivityEventConfigMap().get(treasurePoint.getEventId());
                if (eventConfig == null || eventConfig.getEventType() == eHuaShiGangEventType.BOSS_MONSTER.getValue()) {
                    break;
                }

                int shenXingX = 0;
                int shenXingY = nextTreasureY;
                huaShiGangUserData.reset(shenXingX, shenXingY);

                //找开关
                if (!huaShiGangUserData.getOpenSwitchList().contains(eHuaShiGangSwitchType.TREASURE.getValue())) {
                    isStop = true;
                    break;
                }

                HuaShiGangProto.OpenTreasureFromCross.Builder openTreasure = randomOpenTreasure(serverId, playerId, userBaseInfo);
                if (openTreasure != null) {
                    backMsg.addTreasureResp(openTreasure.build());
                }
                huaShiGangUserData.setFinish(true);
            }

            //找到没有自动开的宝库了,往下找能去的精英
            if (!isStop) {
                shenXing(serverId, playerId, userBaseInfo);
            }
        }

        backMsg.setUserData(HuaShiGangMgr.getHuaShiUserDataGangRespMsg(activityInfo.getActivityId(), serverId, playerId));

        MessageHelper.sendPacket(serverId, playerId,
                YanQuMessageUtils.buildMessage(GameProtocol.S_HUA_SHI_GANG_SHENXING_FROM_CROSS, backMsg));

        return 0;
    }

    /**
     * 修改自动处理开关
     */
    public int updateOpenSwitch(long serverId, long playerId, List<Integer> openSwitchList) {
        HuaShiGangUserData huaShiGangUserData = getUserData(serverId, playerId);
        synchronized (huaShiGangUserData) {
            if (!huaShiGangUserData.getTransportList().contains(1)) {
                return GameErrorCode.E_HUA_SHI_GANG_TRANSPORT_LOCK;
            }
            huaShiGangUserData.setOpenSwitchList(openSwitchList);
            return 0;
        }
    }

    // ======= 偷偷放几个配置 =======

    /**
     * 第x阶段初始单元数
     */
    public int calcUnitCount(int stageIndex) {
        List<List<Integer>> stageTimeList = newConfig.getStageTimeList();
        int subDay;
        if (stageIndex == 0) {
            long time1 = stageTimeList.get(stageIndex).get(1) * DateHelper.MINUTE_MILLIONS;
            int subDay1 = BigDecimal.valueOf(time1).divide(BigDecimal.valueOf(DateHelper.DAY_MILLIONS), 0, BigDecimal.ROUND_UP).intValue();
            subDay = subDay1;
        } else {
            // 例如11号跟12号，差1天；    11号10点跟11号20点，差0天
            long time1 = stageTimeList.get(stageIndex).get(1) * DateHelper.MINUTE_MILLIONS;
            int subDay1 = BigDecimal.valueOf(time1).divide(BigDecimal.valueOf(DateHelper.DAY_MILLIONS), 0, BigDecimal.ROUND_UP).intValue();
            long time2 = stageTimeList.get(stageIndex - 1).get(1) * DateHelper.MINUTE_MILLIONS;
            int subDay2 = BigDecimal.valueOf(time2).divide(BigDecimal.valueOf(DateHelper.DAY_MILLIONS), 0, BigDecimal.ROUND_UP).intValue();
            subDay = subDay1 - subDay2;
        }
        return subDay * newConfig.getDayUnitNum();
    }

    /**
     * 获取每个单元的模块数
     */
    public int getUnitModeCount() {
        return newConfig.getUnitModeNum();
    }

    /**
     * 计算服务器总血量
     */
    public long calcServerTotalHp() {
        long totalHp = 0L;
        for (Long serverId : activityInfo.getServerIdList()) {
            ServerInfo serverInfo = ServerListMgr.getServerInfo(serverId);
            if (serverInfo != null) {
                int openDay = (int) ((activityInfo.getBeginShowTime() - serverInfo.getOpenTime()) / DateHelper.DAY_SECONDS);

                // 拿放大参数
                long enlarge = 0L;
                for (List<Integer> param : newConfig.getServerHpEnlarge()) {
                    enlarge = param.get(1);
                    if (openDay < param.get(0)) {
                        break;
                    }
                }

                // 单服血量
                BigDecimal serverHp = BigDecimal.valueOf(newConfig.getServerBaseHp() * enlarge)
                        .divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_DOWN);

                // 统计
                totalHp = totalHp + serverHp.longValue();
            }
        }

        return totalHp;
    }

    public long calcMonsterHp(int eventId) {
        // 拿平均开服天数
        int totalOpenDay = 0;
        for (Long serverId : activityInfo.getServerIdList()) {
            ServerInfo serverInfo = ServerListMgr.getServerInfo(serverId);
            if (serverInfo != null) {
                totalOpenDay += (int) ((activityInfo.getBeginShowTime() - serverInfo.getOpenTime()) / DateHelper.DAY_SECONDS);
            }
        }
        int avgOpenDay = totalOpenDay / activityInfo.getServerIdList().size();

        // 拿放大参数
        long enlarge = 0L;
        for (List<Integer> param : newConfig.getMonsterHpEnlarge()) {
            enlarge = param.get(1);
            if (avgOpenDay < param.get(0)) {
                break;
            }
        }

        // 特定小怪血量系数
        HuaShiGangActivityEventConfig eventConfig = huaShiGangActivityEventConfigMap.get(eventId);
        Integer hpParam = eventConfig.getBloodParam();

        // 计算血量
        BigDecimal hp = BigDecimal.valueOf(newConfig.getServerBaseHp()).multiply(BigDecimal.valueOf(enlarge)).divide(BigDecimal.valueOf(1000), 8, BigDecimal.ROUND_DOWN)
                .multiply(BigDecimal.valueOf(hpParam)).divide(BigDecimal.valueOf(1000), 8, BigDecimal.ROUND_DOWN);

        return hp.setScale(0, BigDecimal.ROUND_DOWN).longValue();
    }

    public long calcEliteMonsterHp(int eventId, int y) {
        HuaShiGangActivityEventConfig eventConfig = huaShiGangActivityEventConfigMap.get(eventId);
        long totalHp = calcServerTotalHp();

        long blood = totalHp / newConfig.getDayUnitNum() / newConfig.getUnitModeNum();

        blood = blood * eventConfig.getBloodParam() / 1000;

        // 计算援兵加成
        int helperAddition = getHelperAddition(y);
        blood = BigDecimal.valueOf(blood).multiply(BigDecimal.valueOf(1000 + helperAddition)).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_DOWN).longValue();

        return blood;
    }

    public long calcBossHp(String eventParam, int y) {
        List<Integer> paramList = StringUtils.stringToIntegerList(eventParam, "\\|");
        // v6.2 Boss血量计算改为 依照玩家排名门客战力总值获取指定参数
        List<BigInteger> userAbilityList = new ArrayList<>();
        long finalHp = 0L;
        for (HuaShiGangUserData user : userDataMap.values()){
            BigInteger totalAbility;
            if (user.getTotalAbility() <= 0) {
                totalAbility = user.getUserBaseInfo().getTotalAbility();
            } else {
                totalAbility = BigInteger.valueOf(user.getTotalAbility());
            }
            userAbilityList.add(totalAbility);
        }

        userAbilityList.sort(new Comparator<BigInteger>() {
            @Override
            public int compare(BigInteger o1, BigInteger o2) {
                return o2.compareTo(o1);
            }
        });
        int userNumber = userAbilityList.size();
        List<Integer> userFloorEnlarge = newConfig.getUserFloorEnlarge();
        // 根据param的第三个参数，取出第几个Boss的系数
        int bossIndex = paramList.get(2) - 1;
        List<Integer> bossHpEnlarge = newConfig.getBossHpEnlarge().get(bossIndex);
        int startIndex = 0;
        for(int i = 0;i < userFloorEnlarge.size();i++){
            // 找出此处的定位
            int endIndex = userFloorEnlarge.get(i) * userNumber / 1000;
            BigInteger sum = new BigInteger("0");
            for(BigInteger num:userAbilityList.subList(startIndex, endIndex)){
                sum = sum.add(num);
            }
            finalHp += sum.longValue() * bossHpEnlarge.get(i) / 1000;
            startIndex = endIndex;
        }

        //6.5.0 每推进配置的格数boss就增加配置的千分比血量
        if (newConfig.getBossHpParam3().size() >= 2) {
            int everyPosition = newConfig.getBossHpParam3().get(0);
            int everyPositionAddRate = newConfig.getBossHpParam3().get(1);
            int positionAddRate = ((y - 1) / everyPosition) * everyPositionAddRate;
            finalHp += finalHp * positionAddRate / 1000;
        }

        return finalHp;
    }

    public int calcPointMonsterNum() {
        int serverCount = activityInfo.getServerIdList().size();

        int num = 0;
        for (List<Integer> list : newConfig.getPointMonsterNum()) {
            num = list.get(1);
            if (serverCount < list.get(0)) {
                break;
            }
        }

        return num;
    }

    public long calcTotalScore(HuaShiGangMonsterData monsterData) {
        // 开服天数
        long avgOpenDay = 0;
        for (Long serverId : activityInfo.getServerIdList()) {
            avgOpenDay += (activityInfo.getBeginShowTime() - ServerListMgr.getServerInfo(serverId).getOpenTime());
        }
        avgOpenDay = avgOpenDay / activityInfo.getServerIdList().size() / DateHelper.DAY_SECONDS;

        // 积分参数
        int param = 0;
        for (List<Integer> list : newConfig.getScoreCalcParam()) {
            param = list.get(1);
            if (avgOpenDay < list.get(0)) {
                break;
            }
        }

        return BigDecimal.valueOf(monsterData.getAllBlood()).divide(BigDecimal.valueOf(param), 0, BigDecimal.ROUND_DOWN).longValue();
    }

    public long calcDamageScore(HuaShiGangMonsterData monsterData, long damage) {
        long totalScore = calcTotalScore(monsterData);
        BigDecimal percent = BigDecimal.valueOf(damage).divide(BigDecimal.valueOf(monsterData.getAllBlood()), 8, BigDecimal.ROUND_DOWN);
        long score = BigDecimal.valueOf(totalScore).multiply(percent).setScale(0, BigDecimal.ROUND_DOWN).longValue();
        score = Math.max(1, score); // 保底1积分
        return score;
    }

    public long calcKillScore(int x, int y, int id) {
        HuaShiGangMonsterData monsterData = getHuaShiGangMonsterData(x, y, id);
        long totalScore = calcTotalScore(monsterData);

        HuaShiGangActivityEventConfig eventConfig = huaShiGangActivityEventConfigMap.get(getPoint(x, y).getEventId());
        int killScoreParam = eventConfig.getKillScoreParam();

        return BigDecimal.valueOf(totalScore * killScoreParam).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_DOWN).longValue();
    }

    public int getStage(int y) {
        List<List<Integer>> stageTimeList = newConfig.getStageTimeList();
        List<Integer> bossYList = huaShiGangData.getBossYList();

        // y后面boss已生成，这里遍历能找到
        for (int i = 0; i < bossYList.size(); i++) {
            if (y <= bossYList.get(i)) {
                return stageTimeList.get(i).get(0);
            }
        }

        // y后面boss未生成，就找下一个
        int index = Math.min(stageTimeList.size() - 1, bossYList.size());
        return stageTimeList.get(index).get(0);
    }

    public int getHelperAddition(int y) {

        // 还在初始模块
        int initMaxY = calcUnitCount(0) * (newConfig.getUnitModeNum() + 1) * 3;
        if (y <= initMaxY) {
            return 0;
        }

        // 判断前面有多少BOSS
        int bossNum = 0;
        for (Integer bossY : huaShiGangData.getBossYList()) {
            if (y > bossY) {
                bossNum++;
            } else {
                break;
            }
        }

        int helpModeNum = y - initMaxY - bossNum * (newConfig.getUnitModeNum() + 1) * 3;
        int helpUnitNum = BigDecimal.valueOf(helpModeNum).divide(BigDecimal.valueOf(newConfig.getUnitModeNum() + 1), 0, BigDecimal.ROUND_UP).intValue();

        return newConfig.getHelpAddition() * helpUnitNum;
    }

}
